// Package dfareporting provides access to the DCM/DFA Reporting And Trafficking API.
//
// See https://developers.google.com/doubleclick-advertisers/reporting/
//
// Usage example:
//
//   import "google.golang.org/api/dfareporting/v2.0"
//   ...
//   dfareportingService, err := dfareporting.New(oauthHttpClient)
package dfareporting // import "google.golang.org/api/dfareporting/v2.0"

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	context "golang.org/x/net/context"
	ctxhttp "golang.org/x/net/context/ctxhttp"
	gensupport "google.golang.org/api/gensupport"
	googleapi "google.golang.org/api/googleapi"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"
)

// Always reference these packages, just in case the auto-generated code
// below doesn't.
var _ = bytes.NewBuffer
var _ = strconv.Itoa
var _ = fmt.Sprintf
var _ = json.NewDecoder
var _ = io.Copy
var _ = url.Parse
var _ = gensupport.MarshalJSON
var _ = googleapi.Version
var _ = errors.New
var _ = strings.Replace
var _ = context.Canceled
var _ = ctxhttp.Do

const apiId = "dfareporting:v2.0"
const apiName = "dfareporting"
const apiVersion = "v2.0"
const basePath = "https://www.googleapis.com/dfareporting/v2.0/"

// OAuth2 scopes used by this API.
const (
	// View and manage DoubleClick for Advertisers reports
	DfareportingScope = "https://www.googleapis.com/auth/dfareporting"

	// View and manage your DoubleClick Campaign Manager's (DCM) display ad
	// campaigns
	DfatraffickingScope = "https://www.googleapis.com/auth/dfatrafficking"
)

func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.AccountActiveAdSummaries = NewAccountActiveAdSummariesService(s)
	s.AccountPermissionGroups = NewAccountPermissionGroupsService(s)
	s.AccountPermissions = NewAccountPermissionsService(s)
	s.AccountUserProfiles = NewAccountUserProfilesService(s)
	s.Accounts = NewAccountsService(s)
	s.Ads = NewAdsService(s)
	s.AdvertiserGroups = NewAdvertiserGroupsService(s)
	s.Advertisers = NewAdvertisersService(s)
	s.Browsers = NewBrowsersService(s)
	s.CampaignCreativeAssociations = NewCampaignCreativeAssociationsService(s)
	s.Campaigns = NewCampaignsService(s)
	s.ChangeLogs = NewChangeLogsService(s)
	s.Cities = NewCitiesService(s)
	s.ConnectionTypes = NewConnectionTypesService(s)
	s.ContentCategories = NewContentCategoriesService(s)
	s.Countries = NewCountriesService(s)
	s.CreativeAssets = NewCreativeAssetsService(s)
	s.CreativeFieldValues = NewCreativeFieldValuesService(s)
	s.CreativeFields = NewCreativeFieldsService(s)
	s.CreativeGroups = NewCreativeGroupsService(s)
	s.Creatives = NewCreativesService(s)
	s.DimensionValues = NewDimensionValuesService(s)
	s.DirectorySiteContacts = NewDirectorySiteContactsService(s)
	s.DirectorySites = NewDirectorySitesService(s)
	s.EventTags = NewEventTagsService(s)
	s.Files = NewFilesService(s)
	s.FloodlightActivities = NewFloodlightActivitiesService(s)
	s.FloodlightActivityGroups = NewFloodlightActivityGroupsService(s)
	s.FloodlightConfigurations = NewFloodlightConfigurationsService(s)
	s.LandingPages = NewLandingPagesService(s)
	s.Metros = NewMetrosService(s)
	s.MobileCarriers = NewMobileCarriersService(s)
	s.OperatingSystemVersions = NewOperatingSystemVersionsService(s)
	s.OperatingSystems = NewOperatingSystemsService(s)
	s.PlacementGroups = NewPlacementGroupsService(s)
	s.PlacementStrategies = NewPlacementStrategiesService(s)
	s.Placements = NewPlacementsService(s)
	s.PlatformTypes = NewPlatformTypesService(s)
	s.PostalCodes = NewPostalCodesService(s)
	s.Regions = NewRegionsService(s)
	s.Reports = NewReportsService(s)
	s.Sites = NewSitesService(s)
	s.Sizes = NewSizesService(s)
	s.Subaccounts = NewSubaccountsService(s)
	s.UserProfiles = NewUserProfilesService(s)
	s.UserRolePermissionGroups = NewUserRolePermissionGroupsService(s)
	s.UserRolePermissions = NewUserRolePermissionsService(s)
	s.UserRoles = NewUserRolesService(s)
	return s, nil
}

type Service struct {
	client    *http.Client
	BasePath  string // API endpoint base URL
	UserAgent string // optional additional User-Agent fragment

	AccountActiveAdSummaries *AccountActiveAdSummariesService

	AccountPermissionGroups *AccountPermissionGroupsService

	AccountPermissions *AccountPermissionsService

	AccountUserProfiles *AccountUserProfilesService

	Accounts *AccountsService

	Ads *AdsService

	AdvertiserGroups *AdvertiserGroupsService

	Advertisers *AdvertisersService

	Browsers *BrowsersService

	CampaignCreativeAssociations *CampaignCreativeAssociationsService

	Campaigns *CampaignsService

	ChangeLogs *ChangeLogsService

	Cities *CitiesService

	ConnectionTypes *ConnectionTypesService

	ContentCategories *ContentCategoriesService

	Countries *CountriesService

	CreativeAssets *CreativeAssetsService

	CreativeFieldValues *CreativeFieldValuesService

	CreativeFields *CreativeFieldsService

	CreativeGroups *CreativeGroupsService

	Creatives *CreativesService

	DimensionValues *DimensionValuesService

	DirectorySiteContacts *DirectorySiteContactsService

	DirectorySites *DirectorySitesService

	EventTags *EventTagsService

	Files *FilesService

	FloodlightActivities *FloodlightActivitiesService

	FloodlightActivityGroups *FloodlightActivityGroupsService

	FloodlightConfigurations *FloodlightConfigurationsService

	LandingPages *LandingPagesService

	Metros *MetrosService

	MobileCarriers *MobileCarriersService

	OperatingSystemVersions *OperatingSystemVersionsService

	OperatingSystems *OperatingSystemsService

	PlacementGroups *PlacementGroupsService

	PlacementStrategies *PlacementStrategiesService

	Placements *PlacementsService

	PlatformTypes *PlatformTypesService

	PostalCodes *PostalCodesService

	Regions *RegionsService

	Reports *ReportsService

	Sites *SitesService

	Sizes *SizesService

	Subaccounts *SubaccountsService

	UserProfiles *UserProfilesService

	UserRolePermissionGroups *UserRolePermissionGroupsService

	UserRolePermissions *UserRolePermissionsService

	UserRoles *UserRolesService
}

func (s *Service) userAgent() string {
	if s.UserAgent == "" {
		return googleapi.UserAgent
	}
	return googleapi.UserAgent + " " + s.UserAgent
}

func NewAccountActiveAdSummariesService(s *Service) *AccountActiveAdSummariesService {
	rs := &AccountActiveAdSummariesService{s: s}
	return rs
}

type AccountActiveAdSummariesService struct {
	s *Service
}

func NewAccountPermissionGroupsService(s *Service) *AccountPermissionGroupsService {
	rs := &AccountPermissionGroupsService{s: s}
	return rs
}

type AccountPermissionGroupsService struct {
	s *Service
}

func NewAccountPermissionsService(s *Service) *AccountPermissionsService {
	rs := &AccountPermissionsService{s: s}
	return rs
}

type AccountPermissionsService struct {
	s *Service
}

func NewAccountUserProfilesService(s *Service) *AccountUserProfilesService {
	rs := &AccountUserProfilesService{s: s}
	return rs
}

type AccountUserProfilesService struct {
	s *Service
}

func NewAccountsService(s *Service) *AccountsService {
	rs := &AccountsService{s: s}
	return rs
}

type AccountsService struct {
	s *Service
}

func NewAdsService(s *Service) *AdsService {
	rs := &AdsService{s: s}
	return rs
}

type AdsService struct {
	s *Service
}

func NewAdvertiserGroupsService(s *Service) *AdvertiserGroupsService {
	rs := &AdvertiserGroupsService{s: s}
	return rs
}

type AdvertiserGroupsService struct {
	s *Service
}

func NewAdvertisersService(s *Service) *AdvertisersService {
	rs := &AdvertisersService{s: s}
	return rs
}

type AdvertisersService struct {
	s *Service
}

func NewBrowsersService(s *Service) *BrowsersService {
	rs := &BrowsersService{s: s}
	return rs
}

type BrowsersService struct {
	s *Service
}

func NewCampaignCreativeAssociationsService(s *Service) *CampaignCreativeAssociationsService {
	rs := &CampaignCreativeAssociationsService{s: s}
	return rs
}

type CampaignCreativeAssociationsService struct {
	s *Service
}

func NewCampaignsService(s *Service) *CampaignsService {
	rs := &CampaignsService{s: s}
	return rs
}

type CampaignsService struct {
	s *Service
}

func NewChangeLogsService(s *Service) *ChangeLogsService {
	rs := &ChangeLogsService{s: s}
	return rs
}

type ChangeLogsService struct {
	s *Service
}

func NewCitiesService(s *Service) *CitiesService {
	rs := &CitiesService{s: s}
	return rs
}

type CitiesService struct {
	s *Service
}

func NewConnectionTypesService(s *Service) *ConnectionTypesService {
	rs := &ConnectionTypesService{s: s}
	return rs
}

type ConnectionTypesService struct {
	s *Service
}

func NewContentCategoriesService(s *Service) *ContentCategoriesService {
	rs := &ContentCategoriesService{s: s}
	return rs
}

type ContentCategoriesService struct {
	s *Service
}

func NewCountriesService(s *Service) *CountriesService {
	rs := &CountriesService{s: s}
	return rs
}

type CountriesService struct {
	s *Service
}

func NewCreativeAssetsService(s *Service) *CreativeAssetsService {
	rs := &CreativeAssetsService{s: s}
	return rs
}

type CreativeAssetsService struct {
	s *Service
}

func NewCreativeFieldValuesService(s *Service) *CreativeFieldValuesService {
	rs := &CreativeFieldValuesService{s: s}
	return rs
}

type CreativeFieldValuesService struct {
	s *Service
}

func NewCreativeFieldsService(s *Service) *CreativeFieldsService {
	rs := &CreativeFieldsService{s: s}
	return rs
}

type CreativeFieldsService struct {
	s *Service
}

func NewCreativeGroupsService(s *Service) *CreativeGroupsService {
	rs := &CreativeGroupsService{s: s}
	return rs
}

type CreativeGroupsService struct {
	s *Service
}

func NewCreativesService(s *Service) *CreativesService {
	rs := &CreativesService{s: s}
	return rs
}

type CreativesService struct {
	s *Service
}

func NewDimensionValuesService(s *Service) *DimensionValuesService {
	rs := &DimensionValuesService{s: s}
	return rs
}

type DimensionValuesService struct {
	s *Service
}

func NewDirectorySiteContactsService(s *Service) *DirectorySiteContactsService {
	rs := &DirectorySiteContactsService{s: s}
	return rs
}

type DirectorySiteContactsService struct {
	s *Service
}

func NewDirectorySitesService(s *Service) *DirectorySitesService {
	rs := &DirectorySitesService{s: s}
	return rs
}

type DirectorySitesService struct {
	s *Service
}

func NewEventTagsService(s *Service) *EventTagsService {
	rs := &EventTagsService{s: s}
	return rs
}

type EventTagsService struct {
	s *Service
}

func NewFilesService(s *Service) *FilesService {
	rs := &FilesService{s: s}
	return rs
}

type FilesService struct {
	s *Service
}

func NewFloodlightActivitiesService(s *Service) *FloodlightActivitiesService {
	rs := &FloodlightActivitiesService{s: s}
	return rs
}

type FloodlightActivitiesService struct {
	s *Service
}

func NewFloodlightActivityGroupsService(s *Service) *FloodlightActivityGroupsService {
	rs := &FloodlightActivityGroupsService{s: s}
	return rs
}

type FloodlightActivityGroupsService struct {
	s *Service
}

func NewFloodlightConfigurationsService(s *Service) *FloodlightConfigurationsService {
	rs := &FloodlightConfigurationsService{s: s}
	return rs
}

type FloodlightConfigurationsService struct {
	s *Service
}

func NewLandingPagesService(s *Service) *LandingPagesService {
	rs := &LandingPagesService{s: s}
	return rs
}

type LandingPagesService struct {
	s *Service
}

func NewMetrosService(s *Service) *MetrosService {
	rs := &MetrosService{s: s}
	return rs
}

type MetrosService struct {
	s *Service
}

func NewMobileCarriersService(s *Service) *MobileCarriersService {
	rs := &MobileCarriersService{s: s}
	return rs
}

type MobileCarriersService struct {
	s *Service
}

func NewOperatingSystemVersionsService(s *Service) *OperatingSystemVersionsService {
	rs := &OperatingSystemVersionsService{s: s}
	return rs
}

type OperatingSystemVersionsService struct {
	s *Service
}

func NewOperatingSystemsService(s *Service) *OperatingSystemsService {
	rs := &OperatingSystemsService{s: s}
	return rs
}

type OperatingSystemsService struct {
	s *Service
}

func NewPlacementGroupsService(s *Service) *PlacementGroupsService {
	rs := &PlacementGroupsService{s: s}
	return rs
}

type PlacementGroupsService struct {
	s *Service
}

func NewPlacementStrategiesService(s *Service) *PlacementStrategiesService {
	rs := &PlacementStrategiesService{s: s}
	return rs
}

type PlacementStrategiesService struct {
	s *Service
}

func NewPlacementsService(s *Service) *PlacementsService {
	rs := &PlacementsService{s: s}
	return rs
}

type PlacementsService struct {
	s *Service
}

func NewPlatformTypesService(s *Service) *PlatformTypesService {
	rs := &PlatformTypesService{s: s}
	return rs
}

type PlatformTypesService struct {
	s *Service
}

func NewPostalCodesService(s *Service) *PostalCodesService {
	rs := &PostalCodesService{s: s}
	return rs
}

type PostalCodesService struct {
	s *Service
}

func NewRegionsService(s *Service) *RegionsService {
	rs := &RegionsService{s: s}
	return rs
}

type RegionsService struct {
	s *Service
}

func NewReportsService(s *Service) *ReportsService {
	rs := &ReportsService{s: s}
	rs.CompatibleFields = NewReportsCompatibleFieldsService(s)
	rs.Files = NewReportsFilesService(s)
	return rs
}

type ReportsService struct {
	s *Service

	CompatibleFields *ReportsCompatibleFieldsService

	Files *ReportsFilesService
}

func NewReportsCompatibleFieldsService(s *Service) *ReportsCompatibleFieldsService {
	rs := &ReportsCompatibleFieldsService{s: s}
	return rs
}

type ReportsCompatibleFieldsService struct {
	s *Service
}

func NewReportsFilesService(s *Service) *ReportsFilesService {
	rs := &ReportsFilesService{s: s}
	return rs
}

type ReportsFilesService struct {
	s *Service
}

func NewSitesService(s *Service) *SitesService {
	rs := &SitesService{s: s}
	return rs
}

type SitesService struct {
	s *Service
}

func NewSizesService(s *Service) *SizesService {
	rs := &SizesService{s: s}
	return rs
}

type SizesService struct {
	s *Service
}

func NewSubaccountsService(s *Service) *SubaccountsService {
	rs := &SubaccountsService{s: s}
	return rs
}

type SubaccountsService struct {
	s *Service
}

func NewUserProfilesService(s *Service) *UserProfilesService {
	rs := &UserProfilesService{s: s}
	return rs
}

type UserProfilesService struct {
	s *Service
}

func NewUserRolePermissionGroupsService(s *Service) *UserRolePermissionGroupsService {
	rs := &UserRolePermissionGroupsService{s: s}
	return rs
}

type UserRolePermissionGroupsService struct {
	s *Service
}

func NewUserRolePermissionsService(s *Service) *UserRolePermissionsService {
	rs := &UserRolePermissionsService{s: s}
	return rs
}

type UserRolePermissionsService struct {
	s *Service
}

func NewUserRolesService(s *Service) *UserRolesService {
	rs := &UserRolesService{s: s}
	return rs
}

type UserRolesService struct {
	s *Service
}

// Account: Contains properties of a DCM account.
type Account struct {
	// AccountPermissionIds: Account permissions assigned to this account.
	AccountPermissionIds googleapi.Int64s `json:"accountPermissionIds,omitempty"`

	// AccountProfile: Profile for this account. This is a read-only field
	// that can be left blank.
	//
	// Possible values:
	//   "ACCOUNT_PROFILE_BASIC"
	//   "ACCOUNT_PROFILE_STANDARD"
	AccountProfile string `json:"accountProfile,omitempty"`

	// Active: Whether this account is active.
	Active bool `json:"active,omitempty"`

	// ActiveAdsLimitTier: Maximum number of active ads allowed for this
	// account.
	//
	// Possible values:
	//   "ACTIVE_ADS_TIER_100K"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_75K"
	ActiveAdsLimitTier string `json:"activeAdsLimitTier,omitempty"`

	// ActiveViewOptOut: Whether to serve creatives with Active View tags.
	// If disabled, viewability data will not be available for any
	// impressions.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// AvailablePermissionIds: User role permissions available to the user
	// roles of this account.
	AvailablePermissionIds googleapi.Int64s `json:"availablePermissionIds,omitempty"`

	// ComscoreVceEnabled: Whether campaigns created in this account will be
	// enabled for comScore vCE by default.
	ComscoreVceEnabled bool `json:"comscoreVceEnabled,omitempty"`

	// CountryId: ID of the country associated with this account.
	CountryId int64 `json:"countryId,omitempty,string"`

	// CurrencyId: ID of currency associated with this account. This is a
	// required field.
	// Acceptable values are:
	// - "1" for USD
	// - "2" for GBP
	// - "3" for ESP
	// - "4" for SEK
	// - "5" for CAD
	// - "6" for JPY
	// - "7" for DEM
	// - "8" for AUD
	// - "9" for FRF
	// - "10" for ITL
	// - "11" for DKK
	// - "12" for NOK
	// - "13" for FIM
	// - "14" for ZAR
	// - "15" for IEP
	// - "16" for NLG
	// - "17" for EUR
	// - "18" for KRW
	// - "19" for TWD
	// - "20" for SGD
	// - "21" for CNY
	// - "22" for HKD
	// - "23" for NZD
	// - "24" for MYR
	// - "25" for BRL
	// - "26" for PTE
	// - "27" for MXP
	// - "28" for CLP
	// - "29" for TRY
	// - "30" for ARS
	// - "31" for PEN
	// - "32" for ILS
	// - "33" for CHF
	// - "34" for VEF
	// - "35" for COP
	// - "36" for GTQ
	// - "37" for PLN
	// - "39" for INR
	// - "40" for THB
	// - "41" for IDR
	// - "42" for CZK
	// - "43" for RON
	// - "44" for HUF
	// - "45" for RUB
	// - "46" for AED
	// - "47" for BGN
	// - "48" for HRK
	CurrencyId int64 `json:"currencyId,omitempty,string"`

	// DefaultCreativeSizeId: Default placement dimensions for this account.
	DefaultCreativeSizeId int64 `json:"defaultCreativeSizeId,omitempty,string"`

	// Description: Description of this account.
	Description string `json:"description,omitempty"`

	// Id: ID of this account. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#account".
	Kind string `json:"kind,omitempty"`

	// Locale: Locale of this account.
	// Acceptable values are:
	// - "cs" (Czech)
	// - "de" (German)
	// - "en" (English)
	// - "en-GB" (English United Kingdom)
	// - "es" (Spanish)
	// - "fr" (French)
	// - "it" (Italian)
	// - "ja" (Japanese)
	// - "ko" (Korean)
	// - "pl" (Polish)
	// - "pt-BR" (Portuguese Brazil)
	// - "ru" (Russian)
	// - "sv" (Swedish)
	// - "tr" (Turkish)
	// - "zh-CN" (Chinese Simplified)
	// - "zh-TW" (Chinese Traditional)
	Locale string `json:"locale,omitempty"`

	// MaximumImageSize: Maximum image size allowed for this account.
	MaximumImageSize int64 `json:"maximumImageSize,omitempty,string"`

	// Name: Name of this account. This is a required field, and must be
	// less than 128 characters long and be globally unique.
	Name string `json:"name,omitempty"`

	// NielsenOcrEnabled: Whether campaigns created in this account will be
	// enabled for Nielsen OCR reach ratings by default.
	NielsenOcrEnabled bool `json:"nielsenOcrEnabled,omitempty"`

	// ReportsConfiguration: Reporting configuration of this account.
	ReportsConfiguration *ReportsConfiguration `json:"reportsConfiguration,omitempty"`

	// TeaserSizeLimit: File size limit in kilobytes of Rich Media teaser
	// creatives. Must be between 1 and 10240.
	TeaserSizeLimit int64 `json:"teaserSizeLimit,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "AccountPermissionIds") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Account) MarshalJSON() ([]byte, error) {
	type noMethod Account
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountActiveAdSummary: Gets a summary of active ads in an account.
type AccountActiveAdSummary struct {
	// AccountId: ID of the account.
	AccountId int64 `json:"accountId,omitempty,string"`

	// ActiveAds: Ads that have been activated for the account
	ActiveAds int64 `json:"activeAds,omitempty,string"`

	// ActiveAdsLimitTier: Maximum number of active ads allowed for the
	// account.
	//
	// Possible values:
	//   "ACTIVE_ADS_TIER_100K"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_75K"
	ActiveAdsLimitTier string `json:"activeAdsLimitTier,omitempty"`

	// AvailableAds: Ads that can be activated for the account.
	AvailableAds int64 `json:"availableAds,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountActiveAdSummary".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountActiveAdSummary) MarshalJSON() ([]byte, error) {
	type noMethod AccountActiveAdSummary
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountPermission: AccountPermissions contains information about a
// particular account permission. Some features of DCM require an
// account permission to be present in the account.
type AccountPermission struct {
	// AccountProfiles: Account profiles associated with this account
	// permission.
	//
	// Possible values are:
	// - "ACCOUNT_PROFILE_BASIC"
	// - "ACCOUNT_PROFILE_STANDARD"
	//
	// Possible values:
	//   "ACCOUNT_PROFILE_BASIC"
	//   "ACCOUNT_PROFILE_STANDARD"
	AccountProfiles []string `json:"accountProfiles,omitempty"`

	// Id: ID of this account permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermission".
	Kind string `json:"kind,omitempty"`

	// Level: Administrative level required to enable this account
	// permission.
	//
	// Possible values:
	//   "ADMINISTRATOR"
	//   "USER"
	Level string `json:"level,omitempty"`

	// Name: Name of this account permission.
	Name string `json:"name,omitempty"`

	// PermissionGroupId: Permission group of this account permission.
	PermissionGroupId int64 `json:"permissionGroupId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountProfiles") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountPermission) MarshalJSON() ([]byte, error) {
	type noMethod AccountPermission
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountPermissionGroup: AccountPermissionGroups contains a mapping of
// permission group IDs to names. A permission group is a grouping of
// account permissions.
type AccountPermissionGroup struct {
	// Id: ID of this account permission group.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this account permission group.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountPermissionGroup) MarshalJSON() ([]byte, error) {
	type noMethod AccountPermissionGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountPermissionGroupsListResponse: Account Permission Group List
// Response
type AccountPermissionGroupsListResponse struct {
	// AccountPermissionGroups: Account permission group collection.
	AccountPermissionGroups []*AccountPermissionGroup `json:"accountPermissionGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "AccountPermissionGroups") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountPermissionGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AccountPermissionGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountPermissionsListResponse: Account Permission List Response
type AccountPermissionsListResponse struct {
	// AccountPermissions: Account permission collection.
	AccountPermissions []*AccountPermission `json:"accountPermissions,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountPermissionsListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountPermissions")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountPermissionsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AccountPermissionsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountUserProfile: AccountUserProfiles contains properties of a DCM
// user profile. This resource is specifically for managing user
// profiles, whereas UserProfiles is for accessing the API.
type AccountUserProfile struct {
	// AccountId: Account ID of the user profile. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this user profile is active. This defaults to false,
	// and must be set true on insert for the user profile to be usable.
	Active bool `json:"active,omitempty"`

	// AdvertiserFilter: Filter that describes which advertisers are visible
	// to the user profile.
	AdvertiserFilter *ObjectFilter `json:"advertiserFilter,omitempty"`

	// CampaignFilter: Filter that describes which campaigns are visible to
	// the user profile.
	CampaignFilter *ObjectFilter `json:"campaignFilter,omitempty"`

	// Comments: Comments for this user profile.
	Comments string `json:"comments,omitempty"`

	// Email: Email of the user profile. The email addresss must be linked
	// to a Google Account. This field is required on insertion and is
	// read-only after insertion.
	Email string `json:"email,omitempty"`

	// Id: ID of the user profile. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountUserProfile".
	Kind string `json:"kind,omitempty"`

	// Locale: Locale of the user profile. This is a required
	// field.
	// Acceptable values are:
	// - "cs" (Czech)
	// - "de" (German)
	// - "en" (English)
	// - "en-GB" (English United Kingdom)
	// - "es" (Spanish)
	// - "fr" (French)
	// - "it" (Italian)
	// - "ja" (Japanese)
	// - "ko" (Korean)
	// - "pl" (Polish)
	// - "pt-BR" (Portuguese Brazil)
	// - "ru" (Russian)
	// - "sv" (Swedish)
	// - "tr" (Turkish)
	// - "zh-CN" (Chinese Simplified)
	// - "zh-TW" (Chinese Traditional)
	Locale string `json:"locale,omitempty"`

	// Name: Name of the user profile. This is a required field. Must be
	// less than 64 characters long, must be globally unique, and cannot
	// contain whitespace or any of the following characters: "&;"#%,".
	Name string `json:"name,omitempty"`

	// SiteFilter: Filter that describes which sites are visible to the user
	// profile.
	SiteFilter *ObjectFilter `json:"siteFilter,omitempty"`

	// SubaccountId: Subaccount ID of the user profile. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TraffickerType: Trafficker type of this user profile.
	//
	// Possible values:
	//   "EXTERNAL_TRAFFICKER"
	//   "INTERNAL_NON_TRAFFICKER"
	//   "INTERNAL_TRAFFICKER"
	TraffickerType string `json:"traffickerType,omitempty"`

	// UserAccessType: User type of the user profile. This is a read-only
	// field that can be left blank.
	//
	// Possible values:
	//   "INTERNAL_ADMINISTRATOR"
	//   "NORMAL_USER"
	//   "READ_ONLY_SUPER_USER"
	//   "SUPER_USER"
	UserAccessType string `json:"userAccessType,omitempty"`

	// UserRoleFilter: Filter that describes which user roles are visible to
	// the user profile.
	UserRoleFilter *ObjectFilter `json:"userRoleFilter,omitempty"`

	// UserRoleId: User role ID of the user profile. This is a required
	// field.
	UserRoleId int64 `json:"userRoleId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountUserProfile) MarshalJSON() ([]byte, error) {
	type noMethod AccountUserProfile
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountUserProfilesListResponse: Account User Profile List Response
type AccountUserProfilesListResponse struct {
	// AccountUserProfiles: Account user profile collection.
	AccountUserProfiles []*AccountUserProfile `json:"accountUserProfiles,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountUserProfilesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountUserProfiles")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountUserProfilesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AccountUserProfilesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AccountsListResponse: Account List Response
type AccountsListResponse struct {
	// Accounts: Account collection.
	Accounts []*Account `json:"accounts,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#accountsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Accounts") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AccountsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AccountsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Activities: Represents an activity group.
type Activities struct {
	// Filters: List of activity filters. The dimension values need to be
	// all either of type "dfa:activity" or "dfa:activityGroup".
	Filters []*DimensionValue `json:"filters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#activities.
	Kind string `json:"kind,omitempty"`

	// MetricNames: List of names of floodlight activity metrics.
	MetricNames []string `json:"metricNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Filters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Activities) MarshalJSON() ([]byte, error) {
	type noMethod Activities
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Ad: Contains properties of a DCM ad.
type Ad struct {
	// AccountId: Account ID of this ad. This is a read-only field that can
	// be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this ad is active.
	Active bool `json:"active,omitempty"`

	// AdvertiserId: Advertiser ID of this ad. This is a required field on
	// insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this ad is archived.
	Archived bool `json:"archived,omitempty"`

	// AudienceSegmentId: Audience segment ID that is being targeted for
	// this ad. Applicable when type is AD_SERVING_STANDARD_AD.
	AudienceSegmentId int64 `json:"audienceSegmentId,omitempty,string"`

	// CampaignId: Campaign ID of this ad. This is a required field on
	// insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// ClickThroughUrl: Click-through URL for this ad. This is a required
	// field on insertion. Applicable when type is AD_SERVING_CLICK_TRACKER.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// ClickThroughUrlSuffixProperties: Click-through URL suffix properties
	// for this ad. Applies to the URL in the ad or (if overriding ad
	// properties) the URL in the creative.
	ClickThroughUrlSuffixProperties *ClickThroughUrlSuffixProperties `json:"clickThroughUrlSuffixProperties,omitempty"`

	// Comments: Comments for this ad.
	Comments string `json:"comments,omitempty"`

	// Compatibility: Compatibility of this ad. Applicable when type is
	// AD_SERVING_DEFAULT_AD. WEB and WEB_INTERSTITIAL refer to rendering
	// either on desktop or on mobile devices for regular or interstitial
	// ads, respectively. APP and APP_INTERSTITIAL are for rendering in
	// mobile apps. IN_STREAM_VIDEO refers to rendering an in-stream video
	// ads developed with the VAST standard.
	//
	// Possible values:
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "WEB"
	//   "WEB_INTERSTITIAL"
	Compatibility string `json:"compatibility,omitempty"`

	// CreateInfo: Information about the creation of this ad.This is a
	// read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// CreativeGroupAssignments: Creative group assignments for this ad.
	// Applicable when type is AD_SERVING_CLICK_TRACKER. Only one assignment
	// per creative group number is allowed for a maximum of two
	// assignments.
	CreativeGroupAssignments []*CreativeGroupAssignment `json:"creativeGroupAssignments,omitempty"`

	// CreativeRotation: Creative rotation for this ad. Applicable when type
	// is AD_SERVING_DEFAULT_AD, AD_SERVING_STANDARD_AD, or
	// AD_SERVING_TRACKING. When type is AD_SERVING_DEFAULT_AD, this field
	// should have exactly one creativeAssignment.
	CreativeRotation *CreativeRotation `json:"creativeRotation,omitempty"`

	// DayPartTargeting: Time and day targeting information for this ad.
	// Applicable when type is AD_SERVING_STANDARD_AD.
	DayPartTargeting *DayPartTargeting `json:"dayPartTargeting,omitempty"`

	// DefaultClickThroughEventTagProperties: Default click-through event
	// tag properties for this ad.
	DefaultClickThroughEventTagProperties *DefaultClickThroughEventTagProperties `json:"defaultClickThroughEventTagProperties,omitempty"`

	// DeliverySchedule: Delivery schedule information for this ad.
	// Applicable when type is AD_SERVING_STANDARD_AD or
	// AD_SERVING_TRACKING. This field along with subfields priority and
	// impressionRatio are required on insertion when type is
	// AD_SERVING_STANDARD_AD.
	DeliverySchedule *DeliverySchedule `json:"deliverySchedule,omitempty"`

	// DynamicClickTracker: Whether this ad is a dynamic click tracker.
	// Applicable when type is AD_SERVING_CLICK_TRACKER. This is a required
	// field on insert, and is read-only after insert.
	DynamicClickTracker bool `json:"dynamicClickTracker,omitempty"`

	// EndTime: Date and time that this ad should stop serving. Must be
	// later than the start time. This is a required field on insertion.
	EndTime string `json:"endTime,omitempty"`

	// EventTagOverrides: Event tag overrides for this ad.
	EventTagOverrides []*EventTagOverride `json:"eventTagOverrides,omitempty"`

	// GeoTargeting: Geographical targeting information for this
	// ad.Applicable when type is AD_SERVING_STANDARD_AD.
	GeoTargeting *GeoTargeting `json:"geoTargeting,omitempty"`

	// Id: ID of this ad. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this ad. This is a
	// read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyValueTargetingExpression: Key-value targeting information for this
	// ad. Applicable when type is AD_SERVING_STANDARD_AD.
	KeyValueTargetingExpression *KeyValueTargetingExpression `json:"keyValueTargetingExpression,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#ad".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this ad. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this ad. This is a required field and must be less than
	// 256 characters long.
	Name string `json:"name,omitempty"`

	// PlacementAssignments: Placement assignments for this ad.
	PlacementAssignments []*PlacementAssignment `json:"placementAssignments,omitempty"`

	// RemarketingListExpression: Applicable when type is
	// AD_SERVING_STANDARD_AD. Remarketing list targeting expression for
	// this ad.
	RemarketingListExpression *ListTargetingExpression `json:"remarketing_list_expression,omitempty"`

	// Size: Size of this ad. Applicable when type is AD_SERVING_DEFAULT_AD.
	Size *Size `json:"size,omitempty"`

	// SslCompliant: Whether this ad is ssl compliant. This is a read-only
	// field that is auto-generated when the ad is inserted or updated.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// SslRequired: Whether this ad requires ssl. This is a read-only field
	// that is auto-generated when the ad is inserted or updated.
	SslRequired bool `json:"sslRequired,omitempty"`

	// StartTime: Date and time that this ad should start serving. If
	// creating an ad, this field must be a time in the future. This is a
	// required field on insertion.
	StartTime string `json:"startTime,omitempty"`

	// SubaccountId: Subaccount ID of this ad. This is a read-only field
	// that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TechnologyTargeting: Technology platform targeting information for
	// this ad. Applicable when type is AD_SERVING_STANDARD_AD.
	TechnologyTargeting *TechnologyTargeting `json:"technologyTargeting,omitempty"`

	// Type: Type of ad. This is a required field on insertion. Note that
	// default ads (AD_SERVING_DEFAULT_AD) cannot be created directly (see
	// Creative resource).
	//
	// Possible values:
	//   "AD_SERVING_CLICK_TRACKER"
	//   "AD_SERVING_DEFAULT_AD"
	//   "AD_SERVING_STANDARD_AD"
	//   "AD_SERVING_TRACKING"
	Type string `json:"type,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Ad) MarshalJSON() ([]byte, error) {
	type noMethod Ad
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AdsListResponse: Ad List Response
type AdsListResponse struct {
	// Ads: Ad collection.
	Ads []*Ad `json:"ads,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#adsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Ads") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AdsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AdsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Advertiser: Contains properties of a DCM advertiser.
type Advertiser struct {
	// AccountId: Account ID of this advertiser.This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserGroupId: ID of the advertiser group this advertiser belongs
	// to. You can group advertisers for reporting purposes, allowing you to
	// see aggregated information for all advertisers in each group.
	AdvertiserGroupId int64 `json:"advertiserGroupId,omitempty,string"`

	// ClickThroughUrlSuffix: Suffix added to click-through URL of ad
	// creative associations under this advertiser. Must be less than 129
	// characters long.
	ClickThroughUrlSuffix string `json:"clickThroughUrlSuffix,omitempty"`

	// DefaultClickThroughEventTagId: ID of the click-through event tag to
	// apply by default to the landing pages of this advertiser's campaigns.
	DefaultClickThroughEventTagId int64 `json:"defaultClickThroughEventTagId,omitempty,string"`

	// DefaultEmail: Default email address used in sender field for tag
	// emails.
	DefaultEmail string `json:"defaultEmail,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// advertiser. The floodlight configuration ID will be created
	// automatically, so on insert this field should be left blank. This
	// field can be set to another advertiser's floodlight configuration ID
	// in order to share that advertiser's floodlight configuration with
	// this advertiser, so long as:
	// - This advertiser's original floodlight configuration is not already
	// associated with floodlight activities or floodlight activity groups.
	//
	// - This advertiser's original floodlight configuration is not already
	// shared with another advertiser.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// Id: ID of this advertiser. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this advertiser. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiser".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this advertiser. This is a required field and must be
	// less than 256 characters long and unique among advertisers of the
	// same account.
	Name string `json:"name,omitempty"`

	// Status: Status of this advertiser.
	//
	// Possible values:
	//   "APPROVED"
	//   "ON_HOLD"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this advertiser.This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Advertiser) MarshalJSON() ([]byte, error) {
	type noMethod Advertiser
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AdvertiserGroup: Groups advertisers together so that reports can be
// generated for the entire group at once.
type AdvertiserGroup struct {
	// AccountId: Account ID of this advertiser group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Id: ID of this advertiser group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiserGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this advertiser group. This is a required field and
	// must be less than 256 characters long and unique among advertiser
	// groups of the same account.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AdvertiserGroup) MarshalJSON() ([]byte, error) {
	type noMethod AdvertiserGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AdvertiserGroupsListResponse: Advertiser Group List Response
type AdvertiserGroupsListResponse struct {
	// AdvertiserGroups: Advertiser group collection.
	AdvertiserGroups []*AdvertiserGroup `json:"advertiserGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertiserGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AdvertiserGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AdvertiserGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AdvertiserGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AdvertisersListResponse: Advertiser List Response
type AdvertisersListResponse struct {
	// Advertisers: Advertiser collection.
	Advertisers []*Advertiser `json:"advertisers,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#advertisersListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Advertisers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AdvertisersListResponse) MarshalJSON() ([]byte, error) {
	type noMethod AdvertisersListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AudienceSegment: Audience Segment.
type AudienceSegment struct {
	// Allocation: Weight allocated to this segment. Must be between 1 and
	// 1000. The weight assigned will be understood in proportion to the
	// weights assigned to other segments in the same segment group.
	Allocation int64 `json:"allocation,omitempty"`

	// Id: ID of this audience segment. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this audience segment. This is a required field and
	// must be less than 65 characters long.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Allocation") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AudienceSegment) MarshalJSON() ([]byte, error) {
	type noMethod AudienceSegment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// AudienceSegmentGroup: Audience Segment Group.
type AudienceSegmentGroup struct {
	// AudienceSegments: Audience segments assigned to this group. The
	// number of segments must be between 2 and 100.
	AudienceSegments []*AudienceSegment `json:"audienceSegments,omitempty"`

	// Id: ID of this audience segment group. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this audience segment group. This is a required field
	// and must be less than 65 characters long.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AudienceSegments") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *AudienceSegmentGroup) MarshalJSON() ([]byte, error) {
	type noMethod AudienceSegmentGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Browser: Contains information about a browser that can be targeted by
// ads.
type Browser struct {
	// BrowserVersionId: ID referring to this grouping of browser and
	// version numbers. This is the ID used for targeting.
	BrowserVersionId int64 `json:"browserVersionId,omitempty,string"`

	// DartId: DART ID of this browser. This is the ID used when generating
	// reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#browser".
	Kind string `json:"kind,omitempty"`

	// MajorVersion: Major version number (leftmost number) of this browser.
	// For example, for Chrome 5.0.376.86 beta, this field should be set to
	// 5. An asterisk (*) may be used to target any version number, and a
	// question mark (?) may be used to target cases where the version
	// number cannot be identified. For example, Chrome *.* targets any
	// version of Chrome: 1.2, 2.5, 3.5, and so on. Chrome 3.* targets
	// Chrome 3.1, 3.5, but not 4.0. Firefox ?.? targets cases where the ad
	// server knows the browser is Firefox but can't tell which version it
	// is.
	MajorVersion string `json:"majorVersion,omitempty"`

	// MinorVersion: Minor version number (number after first dot on left)
	// of this browser. For example, for Chrome 5.0.375.86 beta, this field
	// should be set to 0. An asterisk (*) may be used to target any version
	// number, and a question mark (?) may be used to target cases where the
	// version number cannot be identified. For example, Chrome *.* targets
	// any version of Chrome: 1.2, 2.5, 3.5, and so on. Chrome 3.* targets
	// Chrome 3.1, 3.5, but not 4.0. Firefox ?.? targets cases where the ad
	// server knows the browser is Firefox but can't tell which version it
	// is.
	MinorVersion string `json:"minorVersion,omitempty"`

	// Name: Name of this browser.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "BrowserVersionId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Browser) MarshalJSON() ([]byte, error) {
	type noMethod Browser
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// BrowsersListResponse: Browser List Response
type BrowsersListResponse struct {
	// Browsers: Browser collection.
	Browsers []*Browser `json:"browsers,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#browsersListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Browsers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *BrowsersListResponse) MarshalJSON() ([]byte, error) {
	type noMethod BrowsersListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Campaign: Contains properties of a DCM campaign.
type Campaign struct {
	// AccountId: Account ID of this campaign. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdditionalCreativeOptimizationConfigurations: Additional creative
	// optimization configurations for the campaign.
	AdditionalCreativeOptimizationConfigurations []*CreativeOptimizationConfiguration `json:"additionalCreativeOptimizationConfigurations,omitempty"`

	// AdvertiserGroupId: Advertiser group ID of the associated advertiser.
	AdvertiserGroupId int64 `json:"advertiserGroupId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this campaign. This is a required
	// field.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the advertiser ID of
	// this campaign. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this campaign has been archived.
	Archived bool `json:"archived,omitempty"`

	// AudienceSegmentGroups: Audience segment groups assigned to this
	// campaign. Cannot have more than 300 segment groups.
	AudienceSegmentGroups []*AudienceSegmentGroup `json:"audienceSegmentGroups,omitempty"`

	// BillingInvoiceCode: Billing invoice code included in the DCM client
	// billing invoices associated with the campaign.
	BillingInvoiceCode string `json:"billingInvoiceCode,omitempty"`

	// ClickThroughUrlSuffixProperties: Click-through URL suffix override
	// properties for this campaign.
	ClickThroughUrlSuffixProperties *ClickThroughUrlSuffixProperties `json:"clickThroughUrlSuffixProperties,omitempty"`

	// Comment: Arbitrary comments about this campaign. Must be less than
	// 256 characters long.
	Comment string `json:"comment,omitempty"`

	// ComscoreVceEnabled: Whether comScore vCE reports are enabled for this
	// campaign.
	ComscoreVceEnabled bool `json:"comscoreVceEnabled,omitempty"`

	// CreateInfo: Information about the creation of this campaign. This is
	// a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// CreativeGroupIds: List of creative group IDs that are assigned to the
	// campaign.
	CreativeGroupIds googleapi.Int64s `json:"creativeGroupIds,omitempty"`

	// CreativeOptimizationConfiguration: Creative optimization
	// configuration for the campaign.
	CreativeOptimizationConfiguration *CreativeOptimizationConfiguration `json:"creativeOptimizationConfiguration,omitempty"`

	// DefaultClickThroughEventTagProperties: Click-through event tag ID
	// override properties for this campaign.
	DefaultClickThroughEventTagProperties *DefaultClickThroughEventTagProperties `json:"defaultClickThroughEventTagProperties,omitempty"`

	// EndDate: Date on which the campaign will stop running. On insert, the
	// end date must be today or a future date. The end date must be later
	// than or be the same as the start date. If, for example, you set
	// 6/25/2015 as both the start and end dates, the effective campaign run
	// date is just that day only, 6/25/2015. The hours, minutes, and
	// seconds of the end date should not be set, as doing so will result in
	// an error. This is a required field.
	EndDate string `json:"endDate,omitempty"`

	// EventTagOverrides: Overrides that can be used to activate or
	// deactivate advertiser event tags.
	EventTagOverrides []*EventTagOverride `json:"eventTagOverrides,omitempty"`

	// ExternalId: External ID for this campaign.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this campaign. This is a read-only auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this campaign. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaign".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this campaign. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// LookbackConfiguration: Lookback window settings for the campaign.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// Name: Name of this campaign. This is a required field and must be
	// less than 256 characters long and unique among campaigns of the same
	// advertiser.
	Name string `json:"name,omitempty"`

	// NielsenOcrEnabled: Whether Nielsen reports are enabled for this
	// campaign.
	NielsenOcrEnabled bool `json:"nielsenOcrEnabled,omitempty"`

	// StartDate: Date on which the campaign starts running. The start date
	// can be any date. The hours, minutes, and seconds of the start date
	// should not be set, as doing so will result in an error. This is a
	// required field.
	StartDate string `json:"startDate,omitempty"`

	// SubaccountId: Subaccount ID of this campaign. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TraffickerEmails: Campaign trafficker contact emails.
	TraffickerEmails []string `json:"traffickerEmails,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Campaign) MarshalJSON() ([]byte, error) {
	type noMethod Campaign
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CampaignCreativeAssociation: Identifies a creative which has been
// associated with a given campaign.
type CampaignCreativeAssociation struct {
	// CreativeId: ID of the creative associated with the campaign. This is
	// a required field.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignCreativeAssociation".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreativeId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CampaignCreativeAssociation) MarshalJSON() ([]byte, error) {
	type noMethod CampaignCreativeAssociation
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CampaignCreativeAssociationsListResponse: Campaign Creative
// Association List Response
type CampaignCreativeAssociationsListResponse struct {
	// CampaignCreativeAssociations: Campaign creative association
	// collection
	CampaignCreativeAssociations []*CampaignCreativeAssociation `json:"campaignCreativeAssociations,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignCreativeAssociationsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "CampaignCreativeAssociations") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CampaignCreativeAssociationsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CampaignCreativeAssociationsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CampaignsListResponse: Campaign List Response
type CampaignsListResponse struct {
	// Campaigns: Campaign collection.
	Campaigns []*Campaign `json:"campaigns,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#campaignsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Campaigns") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CampaignsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CampaignsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ChangeLog: Describes a change that a user has made to a resource.
type ChangeLog struct {
	// AccountId: Account ID of the modified object.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Action: Action which caused the change.
	Action string `json:"action,omitempty"`

	// ChangeTime: Time when the object was modified.
	ChangeTime string `json:"changeTime,omitempty"`

	// FieldName: Field name of the object which changed.
	FieldName string `json:"fieldName,omitempty"`

	// Id: ID of this change log.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#changeLog".
	Kind string `json:"kind,omitempty"`

	// NewValue: New value of the object field.
	NewValue string `json:"newValue,omitempty"`

	// ObjectId: ID of the object of this change log. The object could be a
	// campaign, placement, ad, or other type.
	ObjectId int64 `json:"objectId,omitempty,string"`

	// ObjectType: Object type of the change log.
	ObjectType string `json:"objectType,omitempty"`

	// OldValue: Old value of the object field.
	OldValue string `json:"oldValue,omitempty"`

	// SubaccountId: Subaccount ID of the modified object.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TransactionId: Transaction ID of this change log. When a single API
	// call results in many changes, each change will have a separate ID in
	// the change log but will share the same transactionId.
	TransactionId int64 `json:"transactionId,omitempty,string"`

	// UserProfileId: ID of the user who modified the object.
	UserProfileId int64 `json:"userProfileId,omitempty,string"`

	// UserProfileName: User profile name of the user who modified the
	// object.
	UserProfileName string `json:"userProfileName,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ChangeLog) MarshalJSON() ([]byte, error) {
	type noMethod ChangeLog
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ChangeLogsListResponse: Change Log List Response
type ChangeLogsListResponse struct {
	// ChangeLogs: Change log collection.
	ChangeLogs []*ChangeLog `json:"changeLogs,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#changeLogsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ChangeLogs") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ChangeLogsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod ChangeLogsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CitiesListResponse: City List Response
type CitiesListResponse struct {
	// Cities: City collection.
	Cities []*City `json:"cities,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#citiesListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Cities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CitiesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CitiesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// City: Contains information about a city that can be targeted by ads.
type City struct {
	// CountryCode: Country code of the country to which this city belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this city belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this city. This is the ID used for targeting and
	// generating reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#city".
	Kind string `json:"kind,omitempty"`

	// MetroCode: Metro region code of the metro region (DMA) to which this
	// city belongs.
	MetroCode string `json:"metroCode,omitempty"`

	// MetroDmaId: ID of the metro region (DMA) to which this city belongs.
	MetroDmaId int64 `json:"metroDmaId,omitempty,string"`

	// Name: Name of this city.
	Name string `json:"name,omitempty"`

	// RegionCode: Region code of the region to which this city belongs.
	RegionCode string `json:"regionCode,omitempty"`

	// RegionDartId: DART ID of the region to which this city belongs.
	RegionDartId int64 `json:"regionDartId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *City) MarshalJSON() ([]byte, error) {
	type noMethod City
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ClickTag: Creative Click Tag.
type ClickTag struct {
	// EventName: Advertiser event name associated with the click tag. This
	// field is used by ENHANCED_BANNER, ENHANCED_IMAGE, and HTML5_BANNER
	// creatives.
	EventName string `json:"eventName,omitempty"`

	// Name: Parameter name for the specified click tag. For ENHANCED_IMAGE
	// creative assets, this field must match the value of the creative
	// asset's creativeAssetId.name field.
	Name string `json:"name,omitempty"`

	// Value: Parameter value for the specified click tag. This field
	// contains a click-through url.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EventName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ClickTag) MarshalJSON() ([]byte, error) {
	type noMethod ClickTag
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ClickThroughUrl: Click-through URL
type ClickThroughUrl struct {
	// CustomClickThroughUrl: Custom click-through URL. Applicable if the
	// defaultLandingPage field is set to false and the landingPageId field
	// is left unset.
	CustomClickThroughUrl string `json:"customClickThroughUrl,omitempty"`

	// DefaultLandingPage: Whether the campaign default landing page is
	// used.
	DefaultLandingPage bool `json:"defaultLandingPage,omitempty"`

	// LandingPageId: ID of the landing page for the click-through URL.
	// Applicable if the defaultLandingPage field is set to false.
	LandingPageId int64 `json:"landingPageId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "CustomClickThroughUrl") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ClickThroughUrl) MarshalJSON() ([]byte, error) {
	type noMethod ClickThroughUrl
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ClickThroughUrlSuffixProperties: Click Through URL Suffix settings.
type ClickThroughUrlSuffixProperties struct {
	// ClickThroughUrlSuffix: Click-through URL suffix to apply to all ads
	// in this entity's scope. Must be less than 128 characters long.
	ClickThroughUrlSuffix string `json:"clickThroughUrlSuffix,omitempty"`

	// OverrideInheritedSuffix: Whether this entity should override the
	// inherited click-through URL suffix with its own defined value.
	OverrideInheritedSuffix bool `json:"overrideInheritedSuffix,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ClickThroughUrlSuffix") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ClickThroughUrlSuffixProperties) MarshalJSON() ([]byte, error) {
	type noMethod ClickThroughUrlSuffixProperties
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CompanionClickThroughOverride: Companion Click-through override.
type CompanionClickThroughOverride struct {
	// ClickThroughUrl: Click-through URL of this companion click-through
	// override.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// CreativeId: ID of the creative for this companion click-through
	// override.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "ClickThroughUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CompanionClickThroughOverride) MarshalJSON() ([]byte, error) {
	type noMethod CompanionClickThroughOverride
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CompatibleFields: Represents a response to the queryCompatibleFields
// method.
type CompatibleFields struct {
	// CrossDimensionReachReportCompatibleFields: Contains items that are
	// compatible to be selected for a report of type
	// "CROSS_DIMENSION_REACH".
	CrossDimensionReachReportCompatibleFields *CrossDimensionReachReportCompatibleFields `json:"crossDimensionReachReportCompatibleFields,omitempty"`

	// FloodlightReportCompatibleFields: Contains items that are compatible
	// to be selected for a report of type "FLOODLIGHT".
	FloodlightReportCompatibleFields *FloodlightReportCompatibleFields `json:"floodlightReportCompatibleFields,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#compatibleFields.
	Kind string `json:"kind,omitempty"`

	// PathToConversionReportCompatibleFields: Contains items that are
	// compatible to be selected for a report of type "PATH_TO_CONVERSION".
	PathToConversionReportCompatibleFields *PathToConversionReportCompatibleFields `json:"pathToConversionReportCompatibleFields,omitempty"`

	// ReachReportCompatibleFields: Contains items that are compatible to be
	// selected for a report of type "REACH".
	ReachReportCompatibleFields *ReachReportCompatibleFields `json:"reachReportCompatibleFields,omitempty"`

	// ReportCompatibleFields: Contains items that are compatible to be
	// selected for a report of type "STANDARD".
	ReportCompatibleFields *ReportCompatibleFields `json:"reportCompatibleFields,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "CrossDimensionReachReportCompatibleFields") to unconditionally
	// include in API requests. By default, fields with empty values are
	// omitted from API requests. However, any non-pointer, non-interface
	// field appearing in ForceSendFields will be sent to the server
	// regardless of whether the field is empty or not. This may be used to
	// include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod CompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ConnectionType: Contains information about an internet connection
// type that can be targeted by ads. Clients can use the connection type
// to target mobile vs. broadband users.
type ConnectionType struct {
	// Id: ID of this connection type.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#connectionType".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this connection type.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ConnectionType) MarshalJSON() ([]byte, error) {
	type noMethod ConnectionType
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ConnectionTypesListResponse: Connection Type List Response
type ConnectionTypesListResponse struct {
	// ConnectionTypes: Collection of connection types such as broadband and
	// mobile.
	ConnectionTypes []*ConnectionType `json:"connectionTypes,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#connectionTypesListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ConnectionTypes") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ConnectionTypesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod ConnectionTypesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ContentCategoriesListResponse: Content Category List Response
type ContentCategoriesListResponse struct {
	// ContentCategories: Content category collection.
	ContentCategories []*ContentCategory `json:"contentCategories,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#contentCategoriesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "ContentCategories")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ContentCategoriesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod ContentCategoriesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ContentCategory: Organizes placements according to the contents of
// their associated webpages.
type ContentCategory struct {
	// AccountId: Account ID of this content category. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Description: Description of this content category.
	Description string `json:"description,omitempty"`

	// Id: ID of this content category. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#contentCategory".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this content category. This is a required field and
	// must be less than 256 characters long and unique among content
	// categories of the same account.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ContentCategory) MarshalJSON() ([]byte, error) {
	type noMethod ContentCategory
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CountriesListResponse: Country List Response
type CountriesListResponse struct {
	// Countries: Country collection.
	Countries []*Country `json:"countries,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#countriesListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Countries") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CountriesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CountriesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Country: Contains information about a country that can be targeted by
// ads.
type Country struct {
	// CountryCode: Country code.
	CountryCode string `json:"countryCode,omitempty"`

	// DartId: DART ID of this country. This is the ID used for targeting
	// and generating reports.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#country".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this country.
	Name string `json:"name,omitempty"`

	// SslEnabled: Whether ad serving supports secure servers in this
	// country.
	SslEnabled bool `json:"sslEnabled,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Country) MarshalJSON() ([]byte, error) {
	type noMethod Country
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Creative: Contains properties of a Creative.
type Creative struct {
	// AccountId: Account ID of this creative. This field, if left unset,
	// will be auto-generated for both insert and update operations.
	// Applicable to all creative types.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether the creative is active. Applicable to all creative
	// types.
	Active bool `json:"active,omitempty"`

	// AdParameters: Ad parameters user for VPAID creative. This is a
	// read-only field. Applicable to the following creative types: all
	// VPAID.
	AdParameters string `json:"adParameters,omitempty"`

	// AdTagKeys: Keywords for a Rich Media creative. Keywords let you
	// customize the creative settings of a Rich Media ad running on your
	// site without having to contact the advertiser. You can use keywords
	// to dynamically change the look or functionality of a creative.
	// Applicable to the following creative types: all RICH_MEDIA, and all
	// VPAID.
	AdTagKeys []string `json:"adTagKeys,omitempty"`

	// AdvertiserId: Advertiser ID of this creative. This is a required
	// field. Applicable to all creative types.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AllowScriptAccess: Whether script access is allowed for this
	// creative. This is a read-only and deprecated field which will
	// automatically be set to true on update. Applicable to the following
	// creative types: FLASH_INPAGE.
	AllowScriptAccess bool `json:"allowScriptAccess,omitempty"`

	// Archived: Whether the creative is archived. Applicable to all
	// creative types.
	Archived bool `json:"archived,omitempty"`

	// ArtworkType: Type of artwork used for the creative. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_IMAGE"
	//   "ARTWORK_TYPE_MIXED"
	ArtworkType string `json:"artworkType,omitempty"`

	// AuthoringTool: Authoring tool for HTML5 banner creatives. This is a
	// read-only field. Applicable to the following creative types:
	// HTML5_BANNER.
	//
	// Possible values:
	//   "NINJA"
	//   "SWIFFY"
	AuthoringTool string `json:"authoringTool,omitempty"`

	// AutoAdvanceImages: Whether images are automatically advanced for
	// enhanced image creatives. Applicable to the following creative types:
	// ENHANCED_IMAGE.
	AutoAdvanceImages bool `json:"auto_advance_images,omitempty"`

	// BackgroundColor: The 6-character HTML color code, beginning with #,
	// for the background of the window area where the Flash file is
	// displayed. Default is white. Applicable to the following creative
	// types: FLASH_INPAGE.
	BackgroundColor string `json:"backgroundColor,omitempty"`

	// BackupImageClickThroughUrl: Click-through URL for backup image.
	// Applicable to the following creative types: ENHANCED_BANNER,
	// FLASH_INPAGE, and HTML5_BANNER.
	BackupImageClickThroughUrl string `json:"backupImageClickThroughUrl,omitempty"`

	// BackupImageFeatures: List of feature dependencies that will cause a
	// backup image to be served if the browser that serves the ad does not
	// support them. Feature dependencies are features that a browser must
	// be able to support in order to render your HTML5 creative asset
	// correctly. This field is initially auto-generated to contain all
	// features detected by DCM for all the assets of this creative and can
	// then be modified by the client. To reset this field, copy over all
	// the creativeAssets' detected features. Applicable to the following
	// creative types: ENHANCED_BANNER and HTML5_BANNER.
	//
	// Possible values:
	//   "APPLICATION_CACHE"
	//   "AUDIO"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "CSS_ANIMATIONS"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_COLUMNS"
	//   "CSS_FLEX_BOX"
	//   "CSS_FONT_FACE"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_REFLECTIONS"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "DRAG_AND_DROP"
	//   "GEO_LOCATION"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "INDEXED_DB"
	//   "INLINE_SVG"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_COLOR"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_WEEK"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "SMIL"
	//   "SVG_CLIP_PATHS"
	//   "SVG_FE_IMAGE"
	//   "SVG_FILTERS"
	//   "SVG_HREF"
	//   "TOUCH"
	//   "VIDEO"
	//   "WEBGL"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	BackupImageFeatures []string `json:"backupImageFeatures,omitempty"`

	// BackupImageReportingLabel: Reporting label used for HTML5 banner
	// backup image. Applicable to the following creative types:
	// ENHANCED_BANNER.
	BackupImageReportingLabel string `json:"backupImageReportingLabel,omitempty"`

	// BackupImageTargetWindow: Target window for backup image. Applicable
	// to the following creative types: ENHANCED_BANNER, FLASH_INPAGE, and
	// HTML5_BANNER.
	BackupImageTargetWindow *TargetWindow `json:"backupImageTargetWindow,omitempty"`

	// ClickTags: Click tags of the creative. For ENHANCED_BANNER,
	// FLASH_INPAGE, and HTML5_BANNER creatives, this is a subset of
	// detected click tags for the assets associated with this creative.
	// After creating a flash asset, detected click tags will be returned in
	// the creativeAssetMetadata. When inserting the creative, populate the
	// creative clickTags field using the creativeAssetMetadata.clickTags
	// field. For ENHANCED_IMAGE creatives, there should be exactly one
	// entry in this list for each image creative asset. A click tag is
	// matched with a corresponding creative asset by matching the
	// clickTag.name field with the creativeAsset.assetIdentifier.name
	// field. Applicable to the following creative types: ENHANCED_BANNER,
	// ENHANCED_IMAGE, FLASH_INPAGE, HTML5_BANNER.
	ClickTags []*ClickTag `json:"clickTags,omitempty"`

	// CommercialId: Industry standard ID assigned to creative for reach and
	// frequency. Applicable to the following creative types: all
	// INSTREAM_VIDEO and all VPAID.
	CommercialId string `json:"commercialId,omitempty"`

	// CompanionCreatives: List of companion creatives assigned to an
	// in-Stream videocreative. Acceptable values include IDs of existing
	// flash and image creatives. Applicable to the following creative
	// types: all INSTREAM_VIDEO and all VPAID.
	CompanionCreatives googleapi.Int64s `json:"companionCreatives,omitempty"`

	// Compatibility: Compatibilities associated with this creative. This is
	// a read-only field. WEB and WEB_INTERSTITIAL refer to rendering either
	// on desktop or on mobile devices for regular or interstitial ads,
	// respectively. APP and APP_INTERSTITIAL are for rendering in mobile
	// apps. IN_STREAM_VIDEO refers to rendering in in-stream video ads
	// developed with the VAST standard. Applicable to all creative
	// types.
	//
	// Acceptable values are:
	// - "APP"
	// - "APP_INTERSTITIAL"
	// - "IN_STREAM_VIDEO"
	// - "WEB"
	// - "WEB_INTERSTITIAL"
	//
	// Possible values:
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "WEB"
	//   "WEB_INTERSTITIAL"
	Compatibility []string `json:"compatibility,omitempty"`

	// CounterCustomEvents: List of counter events configured for the
	// creative. For ENHANCED_IMAGE creatives, these are read-only and
	// auto-generated from clickTags. Applicable to the following creative
	// types: ENHANCED_IMAGE, all RICH_MEDIA, and all VPAID.
	CounterCustomEvents []*CreativeCustomEvent `json:"counterCustomEvents,omitempty"`

	// CreativeAssets: Assets associated with a creative. Applicable to all
	// but the following creative types: INTERNAL_REDIRECT,
	// INTERSTITIAL_INTERNAL_REDIRECT, and REDIRECT
	CreativeAssets []*CreativeAsset `json:"creativeAssets,omitempty"`

	// CreativeFieldAssignments: Creative field assignments for this
	// creative. Applicable to all creative types.
	CreativeFieldAssignments []*CreativeFieldAssignment `json:"creativeFieldAssignments,omitempty"`

	// CustomKeyValues: Custom key-values for a Rich Media creative.
	// Key-values let you customize the creative settings of a Rich Media ad
	// running on your site without having to contact the advertiser. You
	// can use key-values to dynamically change the look or functionality of
	// a creative. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	CustomKeyValues []string `json:"customKeyValues,omitempty"`

	// ExitCustomEvents: List of exit events configured for the creative.
	// For ENHANCED_BANNER and ENHANCED_IMAGE creatives, these are read-only
	// and auto-generated from clickTags, For ENHANCED_BANNER, an event is
	// also created from the backupImageReportingLabel. Applicable to the
	// following creative types: ENHANCED_BANNER, ENHANCED_IMAGE, all
	// RICH_MEDIA, and all VPAID.
	ExitCustomEvents []*CreativeCustomEvent `json:"exitCustomEvents,omitempty"`

	// FsCommand: OpenWindow FSCommand of this creative. This lets the SWF
	// file communicate with either Flash Player or the program hosting
	// Flash Player, such as a web browser. This is only triggered if
	// allowScriptAccess field is true. Applicable to the following creative
	// types: FLASH_INPAGE.
	FsCommand *FsCommand `json:"fsCommand,omitempty"`

	// HtmlCode: HTML code for the creative. This is a required field when
	// applicable. This field is ignored if htmlCodeLocked is false.
	// Applicable to the following creative types: all CUSTOM, FLASH_INPAGE,
	// and HTML5_BANNER, and all RICH_MEDIA.
	HtmlCode string `json:"htmlCode,omitempty"`

	// HtmlCodeLocked: Whether HTML code is DCM-generated or manually
	// entered. Set to true to ignore changes to htmlCode. Applicable to the
	// following creative types: FLASH_INPAGE and HTML5_BANNER.
	HtmlCodeLocked bool `json:"htmlCodeLocked,omitempty"`

	// Id: ID of this creative. This is a read-only, auto-generated field.
	// Applicable to all creative types.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this creative. This
	// is a read-only field. Applicable to all creative types.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creative".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Creative last modification information. This is a
	// read-only field. Applicable to all creative types.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// LatestTraffickedCreativeId: Latest Studio trafficked creative ID
	// associated with rich media and VPAID creatives. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA,
	// and all VPAID.
	LatestTraffickedCreativeId int64 `json:"latestTraffickedCreativeId,omitempty,string"`

	// Name: Name of the creative. This is a required field and must be less
	// than 256 characters long. Applicable to all creative types.
	Name string `json:"name,omitempty"`

	// OverrideCss: Override CSS value for rich media creatives. Applicable
	// to the following creative types: all RICH_MEDIA.
	OverrideCss string `json:"overrideCss,omitempty"`

	// RedirectUrl: URL of hosted image or hosted video or another ad tag.
	// For INSTREAM_VIDEO_REDIRECT creatives this is the in-stream video
	// redirect URL. The standard for a VAST (Video Ad Serving Template) ad
	// response allows for a redirect link to another VAST 2.0 or 3.0 call.
	// This is a required field when applicable. Applicable to the following
	// creative types: INTERNAL_REDIRECT, INTERSTITIAL_INTERNAL_REDIRECT,
	// REDIRECT, and INSTREAM_VIDEO_REDIRECT
	RedirectUrl string `json:"redirectUrl,omitempty"`

	// RenderingId: ID of current rendering version. This is a read-only
	// field. Applicable to all creative types.
	RenderingId int64 `json:"renderingId,omitempty,string"`

	// RenderingIdDimensionValue: Dimension value for the rendering ID of
	// this creative. This is a read-only field. Applicable to all creative
	// types.
	RenderingIdDimensionValue *DimensionValue `json:"renderingIdDimensionValue,omitempty"`

	// RequiredFlashPluginVersion: The minimum required Flash plugin version
	// for this creative. For example, 11.2.202.235. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA,
	// and all VPAID.
	RequiredFlashPluginVersion string `json:"requiredFlashPluginVersion,omitempty"`

	// RequiredFlashVersion: The internal Flash version for this creative as
	// calculated by DoubleClick Studio. This is a read-only field.
	// Applicable to the following creative types: FLASH_INPAGE,
	// ENHANCED_BANNER, all RICH_MEDIA, and all VPAID.
	RequiredFlashVersion int64 `json:"requiredFlashVersion,omitempty"`

	// Size: Size associated with this creative. When inserting or updating
	// a creative either the size ID field or size width and height fields
	// can be used. This is a required field when applicable; however for
	// IMAGE and FLASH_INPAGE creatives, if left blank, this field will be
	// automatically set using the actual size of the associated image
	// assets. Applicable to the following creative types: ENHANCED_BANNER,
	// ENHANCED_IMAGE, FLASH_INPAGE, HTML5_BANNER, IMAGE, and all
	// RICH_MEDIA.
	Size *Size `json:"size,omitempty"`

	// Skippable: Whether the user can choose to skip the creative.
	// Applicable to the following creative types: all INSTREAM_VIDEO and
	// all VPAID.
	Skippable bool `json:"skippable,omitempty"`

	// SslCompliant: Whether the creative is SSL-compliant. This is a
	// read-only field. Applicable to all creative types.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// StudioAdvertiserId: Studio advertiser ID associated with rich media
	// and VPAID creatives. This is a read-only field. Applicable to the
	// following creative types: all RICH_MEDIA, and all VPAID.
	StudioAdvertiserId int64 `json:"studioAdvertiserId,omitempty,string"`

	// StudioCreativeId: Studio creative ID associated with rich media and
	// VPAID creatives. This is a read-only field. Applicable to the
	// following creative types: all RICH_MEDIA, and all VPAID.
	StudioCreativeId int64 `json:"studioCreativeId,omitempty,string"`

	// StudioTraffickedCreativeId: Studio trafficked creative ID associated
	// with rich media and VPAID creatives. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA, and all
	// VPAID.
	StudioTraffickedCreativeId int64 `json:"studioTraffickedCreativeId,omitempty,string"`

	// SubaccountId: Subaccount ID of this creative. This field, if left
	// unset, will be auto-generated for both insert and update operations.
	// Applicable to all creative types.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ThirdPartyBackupImageImpressionsUrl: Third-party URL used to record
	// backup image impressions. Applicable to the following creative types:
	// all RICH_MEDIA
	ThirdPartyBackupImageImpressionsUrl string `json:"thirdPartyBackupImageImpressionsUrl,omitempty"`

	// ThirdPartyRichMediaImpressionsUrl: Third-party URL used to record
	// rich media impressions. Applicable to the following creative types:
	// all RICH_MEDIA
	ThirdPartyRichMediaImpressionsUrl string `json:"thirdPartyRichMediaImpressionsUrl,omitempty"`

	// ThirdPartyUrls: Third-party URLs for tracking in-stream video
	// creative events. Applicable to the following creative types: all
	// INSTREAM_VIDEO and all VPAID.
	ThirdPartyUrls []*ThirdPartyTrackingUrl `json:"thirdPartyUrls,omitempty"`

	// TimerCustomEvents: List of timer events configured for the creative.
	// For ENHANCED_IMAGE creatives, these are read-only and auto-generated
	// from clickTags. Applicable to the following creative types:
	// ENHANCED_IMAGE, all RICH_MEDIA, and all VPAID.
	TimerCustomEvents []*CreativeCustomEvent `json:"timerCustomEvents,omitempty"`

	// TotalFileSize: Combined size of all creative assets. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA, and all VPAID.
	TotalFileSize int64 `json:"totalFileSize,omitempty,string"`

	// Type: Type of this creative.This is a required field. Applicable to
	// all creative types.
	//
	// Possible values:
	//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
	//   "CUSTOM_INPAGE"
	//   "CUSTOM_INTERSTITIAL"
	//   "ENHANCED_BANNER"
	//   "ENHANCED_IMAGE"
	//   "FLASH_INPAGE"
	//   "HTML5_BANNER"
	//   "IMAGE"
	//   "INSTREAM_VIDEO"
	//   "INTERNAL_REDIRECT"
	//   "INTERSTITIAL_INTERNAL_REDIRECT"
	//   "REDIRECT"
	//   "RICH_MEDIA_EXPANDING"
	//   "RICH_MEDIA_IM_EXPAND"
	//   "RICH_MEDIA_INPAGE"
	//   "RICH_MEDIA_INPAGE_FLOATING"
	//   "RICH_MEDIA_INTERSTITIAL_FLOAT"
	//   "RICH_MEDIA_MOBILE_IN_APP"
	//   "RICH_MEDIA_MULTI_FLOATING"
	//   "RICH_MEDIA_PEEL_DOWN"
	//   "TRACKING_TEXT"
	//   "VAST_REDIRECT"
	//   "VPAID_LINEAR"
	//   "VPAID_NON_LINEAR"
	Type string `json:"type,omitempty"`

	// Version: The version number helps you keep track of multiple versions
	// of your creative in your reports. The version number will always be
	// auto-generated during insert operations to start at 1. For tracking
	// creatives the version cannot be incremented and will always remain at
	// 1. For all other creative types the version can be incremented only
	// by 1 during update operations. In addition, the version will be
	// automatically incremented by 1 when undergoing Rich Media creative
	// merging. Applicable to all creative types.
	Version int64 `json:"version,omitempty"`

	// VideoDescription: Description of the video ad. Applicable to the
	// following creative types: all INSTREAM_VIDEO and all VPAID.
	VideoDescription string `json:"videoDescription,omitempty"`

	// VideoDuration: Creative video duration in seconds. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO, all RICH_MEDIA, and all VPAID.
	VideoDuration float64 `json:"videoDuration,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Creative) MarshalJSON() ([]byte, error) {
	type noMethod Creative
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeAsset: Creative Asset.
type CreativeAsset struct {
	// ActionScript3: Whether ActionScript3 is enabled for the flash asset.
	// This is a read-only field. Applicable to the following creative
	// types: FLASH_INPAGE and ENHANCED_BANNER.
	ActionScript3 bool `json:"actionScript3,omitempty"`

	// Active: Whether the video asset is active. This is a read-only field
	// for VPAID_NON_LINEAR assets. Applicable to the following creative
	// types: INSTREAM_VIDEO and all VPAID.
	Active bool `json:"active,omitempty"`

	// Alignment: Possible alignments for an asset. This is a read-only
	// field. Applicable to the following creative types:
	// RICH_MEDIA_MULTI_FLOATING.
	//
	// Possible values:
	//   "ALIGNMENT_BOTTOM"
	//   "ALIGNMENT_LEFT"
	//   "ALIGNMENT_RIGHT"
	//   "ALIGNMENT_TOP"
	Alignment string `json:"alignment,omitempty"`

	// ArtworkType: Artwork type of rich media creative. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_IMAGE"
	//   "ARTWORK_TYPE_MIXED"
	ArtworkType string `json:"artworkType,omitempty"`

	// AssetIdentifier: Identifier of this asset. This is the same
	// identifier returned during creative asset insert operation. This is a
	// required field. Applicable to all but the following creative types:
	// all REDIRECT and TRACKING_TEXT.
	AssetIdentifier *CreativeAssetId `json:"assetIdentifier,omitempty"`

	// BackupImageExit: Exit event configured for the backup image.
	// Applicable to the following creative types: all RICH_MEDIA.
	BackupImageExit *CreativeCustomEvent `json:"backupImageExit,omitempty"`

	// BitRate: Detected bit-rate for video asset. This is a read-only
	// field. Applicable to the following creative types: INSTREAM_VIDEO and
	// all VPAID.
	BitRate int64 `json:"bitRate,omitempty"`

	// ChildAssetType: Rich media child asset type. This is a read-only
	// field. Applicable to the following creative types: all VPAID.
	//
	// Possible values:
	//   "CHILD_ASSET_TYPE_DATA"
	//   "CHILD_ASSET_TYPE_FLASH"
	//   "CHILD_ASSET_TYPE_IMAGE"
	//   "CHILD_ASSET_TYPE_VIDEO"
	ChildAssetType string `json:"childAssetType,omitempty"`

	// CollapsedSize: Size of an asset when collapsed. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA and
	// all VPAID. Additionally, applicable to assets whose displayType is
	// ASSET_DISPLAY_TYPE_EXPANDING or ASSET_DISPLAY_TYPE_PEEL_DOWN.
	CollapsedSize *Size `json:"collapsedSize,omitempty"`

	// CustomStartTimeValue: Custom start time in seconds for making the
	// asset visible. Applicable to the following creative types: all
	// RICH_MEDIA.
	CustomStartTimeValue int64 `json:"customStartTimeValue,omitempty"`

	// DetectedFeatures: List of feature dependencies for the creative asset
	// that are detected by DCM. Feature dependencies are features that a
	// browser must be able to support in order to render your HTML5
	// creative correctly. This is a read-only, auto-generated field.
	// Applicable to the following creative types: ENHANCED_BANNER and
	// HTML5_BANNER.
	//
	// Possible values:
	//   "APPLICATION_CACHE"
	//   "AUDIO"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "CSS_ANIMATIONS"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_COLUMNS"
	//   "CSS_FLEX_BOX"
	//   "CSS_FONT_FACE"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_REFLECTIONS"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "DRAG_AND_DROP"
	//   "GEO_LOCATION"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "INDEXED_DB"
	//   "INLINE_SVG"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_COLOR"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_WEEK"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "SMIL"
	//   "SVG_CLIP_PATHS"
	//   "SVG_FE_IMAGE"
	//   "SVG_FILTERS"
	//   "SVG_HREF"
	//   "TOUCH"
	//   "VIDEO"
	//   "WEBGL"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	DetectedFeatures []string `json:"detectedFeatures,omitempty"`

	// DisplayType: Type of rich media asset. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_DISPLAY_TYPE_EXPANDING"
	//   "ASSET_DISPLAY_TYPE_FLASH_IN_FLASH"
	//   "ASSET_DISPLAY_TYPE_FLASH_IN_FLASH_EXPANDING"
	//   "ASSET_DISPLAY_TYPE_FLOATING"
	//   "ASSET_DISPLAY_TYPE_INPAGE"
	//   "ASSET_DISPLAY_TYPE_OVERLAY"
	//   "ASSET_DISPLAY_TYPE_PEEL_DOWN"
	//   "ASSET_DISPLAY_TYPE_VPAID_LINEAR"
	//   "ASSET_DISPLAY_TYPE_VPAID_NON_LINEAR"
	DisplayType string `json:"displayType,omitempty"`

	// Duration: Duration in seconds for which an asset will be displayed.
	// Applicable to the following creative types: INSTREAM_VIDEO and
	// VPAID_LINEAR.
	Duration int64 `json:"duration,omitempty"`

	// DurationType: Duration type for which an asset will be displayed.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_DURATION_TYPE_AUTO"
	//   "ASSET_DURATION_TYPE_CUSTOM"
	//   "ASSET_DURATION_TYPE_NONE"
	DurationType string `json:"durationType,omitempty"`

	// ExpandedDimension: Detected expanded dimension for video asset. This
	// is a read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	ExpandedDimension *Size `json:"expandedDimension,omitempty"`

	// FileSize: File size associated with this creative asset. This is a
	// read-only field. Applicable to all but the following creative types:
	// all REDIRECT and TRACKING_TEXT.
	FileSize int64 `json:"fileSize,omitempty,string"`

	// FlashVersion: Flash version of the asset. This is a read-only field.
	// Applicable to the following creative types: FLASH_INPAGE,
	// ENHANCED_BANNER, all RICH_MEDIA, and all VPAID.
	FlashVersion int64 `json:"flashVersion,omitempty"`

	// HideFlashObjects: Whether to hide Flash objects flag for an asset.
	// Applicable to the following creative types: all RICH_MEDIA.
	HideFlashObjects bool `json:"hideFlashObjects,omitempty"`

	// HideSelectionBoxes: Whether to hide selection boxes flag for an
	// asset. Applicable to the following creative types: all RICH_MEDIA.
	HideSelectionBoxes bool `json:"hideSelectionBoxes,omitempty"`

	// HorizontallyLocked: Whether the asset is horizontally locked. This is
	// a read-only field. Applicable to the following creative types: all
	// RICH_MEDIA.
	HorizontallyLocked bool `json:"horizontallyLocked,omitempty"`

	// Id: Numeric ID of this creative asset. This is a required field and
	// should not be modified. Applicable to all but the following creative
	// types: all REDIRECT and TRACKING_TEXT.
	Id int64 `json:"id,omitempty,string"`

	// MimeType: Detected MIME type for video asset. This is a read-only
	// field. Applicable to the following creative types: INSTREAM_VIDEO and
	// all VPAID.
	MimeType string `json:"mimeType,omitempty"`

	// Offset: Offset position for an asset in collapsed mode. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA and all VPAID. Additionally, only applicable to assets
	// whose displayType is ASSET_DISPLAY_TYPE_EXPANDING or
	// ASSET_DISPLAY_TYPE_PEEL_DOWN.
	Offset *OffsetPosition `json:"offset,omitempty"`

	// OriginalBackup: Whether the backup asset is original or changed by
	// the user in DCM. Applicable to the following creative types: all
	// RICH_MEDIA.
	OriginalBackup bool `json:"originalBackup,omitempty"`

	// Position: Offset position for an asset. Applicable to the following
	// creative types: all RICH_MEDIA.
	Position *OffsetPosition `json:"position,omitempty"`

	// PositionLeftUnit: Offset left unit for an asset. This is a read-only
	// field. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "OFFSET_UNIT_PERCENT"
	//   "OFFSET_UNIT_PIXEL"
	//   "OFFSET_UNIT_PIXEL_FROM_CENTER"
	PositionLeftUnit string `json:"positionLeftUnit,omitempty"`

	// PositionTopUnit: Offset top unit for an asset. This is a read-only
	// field if the asset displayType is ASSET_DISPLAY_TYPE_OVERLAY.
	// Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "OFFSET_UNIT_PERCENT"
	//   "OFFSET_UNIT_PIXEL"
	//   "OFFSET_UNIT_PIXEL_FROM_CENTER"
	PositionTopUnit string `json:"positionTopUnit,omitempty"`

	// ProgressiveServingUrl: Progressive URL for video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	ProgressiveServingUrl string `json:"progressiveServingUrl,omitempty"`

	// Pushdown: Whether the asset pushes down other content. Applicable to
	// the following creative types: all RICH_MEDIA. Additionally, only
	// applicable when the asset offsets are 0, the collapsedSize.width
	// matches size.width, and the collapsedSize.height is less than
	// size.height.
	Pushdown bool `json:"pushdown,omitempty"`

	// PushdownDuration: Pushdown duration in seconds for an asset. Must be
	// between 0 and 9.99. Applicable to the following creative types: all
	// RICH_MEDIA.Additionally, only applicable when the asset pushdown
	// field is true, the offsets are 0, the collapsedSize.width matches
	// size.width, and the collapsedSize.height is less than size.height.
	PushdownDuration float64 `json:"pushdownDuration,omitempty"`

	// Role: Role of the asset in relation to creative. Applicable to all
	// but the following creative types: all REDIRECT and TRACKING_TEXT.
	// This is a required field.
	// PRIMARY applies to ENHANCED_BANNER, FLASH_INPAGE, HTML5_BANNER,
	// IMAGE, IMAGE_GALLERY, all RICH_MEDIA (which may contain multiple
	// primary assets), and all VPAID creatives.
	// BACKUP_IMAGE applies to ENHANCED_BANNER, FLASH_INPAGE, HTML5_BANNER,
	// all RICH_MEDIA, and all VPAID creatives.
	// ADDITIONAL_IMAGE and ADDITIONAL_FLASH apply to FLASH_INPAGE
	// creatives.
	// OTHER refers to assets from sources other than DCM, such as Studio
	// uploaded assets, applicable to all RICH_MEDIA and all VPAID
	// creatives.
	// PARENT_VIDEO refers to videos uploaded by the user in DCM and is
	// applicable to INSTREAM_VIDEO and VPAID_LINEAR
	// creatives.
	// TRANSCODED_VIDEO refers to videos transcoded by DCM from PARENT_VIDEO
	// assets and is applicable to INSTREAM_VIDEO and VPAID_LINEAR
	// creatives.
	// ALTERNATE_VIDEO refers to the DCM representation of child asset
	// videos from Studio, and is applicable to VPAID_LINEAR creatives.
	// These cannot be added or removed within DCM.
	// For VPAID_LINEAR creatives, PARENT_VIDEO, TRANSCODED_VIDEO and
	// ALTERNATE_VIDEO assets that are marked active serve as backup in case
	// the VPAID creative cannot be served. Only PARENT_VIDEO assets can be
	// added or removed for an INSTREAM_VIDEO or VPAID_LINEAR creative.
	//
	// Possible values:
	//   "ADDITIONAL_FLASH"
	//   "ADDITIONAL_IMAGE"
	//   "ALTERNATE_VIDEO"
	//   "BACKUP_IMAGE"
	//   "OTHER"
	//   "PARENT_VIDEO"
	//   "PRIMARY"
	//   "TRANSCODED_VIDEO"
	Role string `json:"role,omitempty"`

	// Size: Size associated with this creative asset. This is a required
	// field when applicable; however for IMAGE and FLASH_INPAGE creatives,
	// if left blank, this field will be automatically set using the actual
	// size of the associated image asset. Applicable to the following
	// creative types: ENHANCED_BANNER, ENHANCED_IMAGE, FLASH_INPAGE,
	// HTML5_BANNER, IMAGE, and all RICH_MEDIA.
	Size *Size `json:"size,omitempty"`

	// SslCompliant: Whether the asset is SSL-compliant. This is a read-only
	// field. Applicable to all but the following creative types: all
	// REDIRECT and TRACKING_TEXT.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// StartTimeType: Initial wait time type before making the asset
	// visible. Applicable to the following creative types: all RICH_MEDIA.
	//
	// Possible values:
	//   "ASSET_START_TIME_TYPE_CUSTOM"
	//   "ASSET_START_TIME_TYPE_NONE"
	StartTimeType string `json:"startTimeType,omitempty"`

	// StreamingServingUrl: Streaming URL for video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	StreamingServingUrl string `json:"streamingServingUrl,omitempty"`

	// Transparency: Whether the asset is transparent. Applicable to the
	// following creative types: all RICH_MEDIA. Additionally, only
	// applicable to HTML5 assets.
	Transparency bool `json:"transparency,omitempty"`

	// VerticallyLocked: Whether the asset is vertically locked. This is a
	// read-only field. Applicable to the following creative types: all
	// RICH_MEDIA.
	VerticallyLocked bool `json:"verticallyLocked,omitempty"`

	// VideoDuration: Detected video duration for video asset. This is a
	// read-only field. Applicable to the following creative types:
	// INSTREAM_VIDEO and all VPAID.
	VideoDuration float64 `json:"videoDuration,omitempty"`

	// WindowMode: Window mode options for flash assets. Applicable to the
	// following creative types: FLASH_INPAGE, RICH_MEDIA_EXPANDING,
	// RICH_MEDIA_IM_EXPAND, RICH_MEDIA_INPAGE, and
	// RICH_MEDIA_INPAGE_FLOATING.
	//
	// Possible values:
	//   "OPAQUE"
	//   "TRANSPARENT"
	//   "WINDOW"
	WindowMode string `json:"windowMode,omitempty"`

	// ZIndex: zIndex value of an asset. This is a read-only field.
	// Applicable to the following creative types: all
	// RICH_MEDIA.Additionally, only applicable to assets whose displayType
	// is NOT one of the following types: ASSET_DISPLAY_TYPE_INPAGE or
	// ASSET_DISPLAY_TYPE_OVERLAY.
	ZIndex int64 `json:"zIndex,omitempty"`

	// ZipFilename: File name of zip file. This is a read-only field.
	// Applicable to the following creative types: HTML5_BANNER.
	ZipFilename string `json:"zipFilename,omitempty"`

	// ZipFilesize: Size of zip file. This is a read-only field. Applicable
	// to the following creative types: HTML5_BANNER.
	ZipFilesize string `json:"zipFilesize,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActionScript3") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeAsset) MarshalJSON() ([]byte, error) {
	type noMethod CreativeAsset
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeAssetId: Creative Asset ID.
type CreativeAssetId struct {
	// Name: Name of the creative asset. This is a required field while
	// inserting an asset. After insertion, this assetIdentifier is used to
	// identify the uploaded asset. Characters in the name must be
	// alphanumeric or one of the following: ".-_ ". Spaces are allowed.
	Name string `json:"name,omitempty"`

	// Type: Type of asset to upload. This is a required field. IMAGE is
	// solely used for IMAGE creatives. Other image assets should use
	// HTML_IMAGE.
	//
	// Possible values:
	//   "FLASH"
	//   "HTML"
	//   "HTML_IMAGE"
	//   "IMAGE"
	//   "VIDEO"
	Type string `json:"type,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Name") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeAssetId) MarshalJSON() ([]byte, error) {
	type noMethod CreativeAssetId
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeAssetMetadata: CreativeAssets contains properties of a
// creative asset file which will be uploaded or has already been
// uploaded. Refer to the creative sample code for how to upload assets
// and insert a creative.
type CreativeAssetMetadata struct {
	// AssetIdentifier: ID of the creative asset. This is a required field.
	AssetIdentifier *CreativeAssetId `json:"assetIdentifier,omitempty"`

	// ClickTags: List of detected click tags for assets. This is a
	// read-only auto-generated field.
	ClickTags []*ClickTag `json:"clickTags,omitempty"`

	// DetectedFeatures: List of feature dependencies for the creative asset
	// that are detected by DCM. Feature dependencies are features that a
	// browser must be able to support in order to render your HTML5
	// creative correctly. This is a read-only, auto-generated field.
	//
	// Possible values:
	//   "APPLICATION_CACHE"
	//   "AUDIO"
	//   "CANVAS"
	//   "CANVAS_TEXT"
	//   "CSS_ANIMATIONS"
	//   "CSS_BACKGROUND_SIZE"
	//   "CSS_BORDER_IMAGE"
	//   "CSS_BORDER_RADIUS"
	//   "CSS_BOX_SHADOW"
	//   "CSS_COLUMNS"
	//   "CSS_FLEX_BOX"
	//   "CSS_FONT_FACE"
	//   "CSS_GENERATED_CONTENT"
	//   "CSS_GRADIENTS"
	//   "CSS_HSLA"
	//   "CSS_MULTIPLE_BGS"
	//   "CSS_OPACITY"
	//   "CSS_REFLECTIONS"
	//   "CSS_RGBA"
	//   "CSS_TEXT_SHADOW"
	//   "CSS_TRANSFORMS"
	//   "CSS_TRANSFORMS3D"
	//   "CSS_TRANSITIONS"
	//   "DRAG_AND_DROP"
	//   "GEO_LOCATION"
	//   "HASH_CHANGE"
	//   "HISTORY"
	//   "INDEXED_DB"
	//   "INLINE_SVG"
	//   "INPUT_ATTR_AUTOCOMPLETE"
	//   "INPUT_ATTR_AUTOFOCUS"
	//   "INPUT_ATTR_LIST"
	//   "INPUT_ATTR_MAX"
	//   "INPUT_ATTR_MIN"
	//   "INPUT_ATTR_MULTIPLE"
	//   "INPUT_ATTR_PATTERN"
	//   "INPUT_ATTR_PLACEHOLDER"
	//   "INPUT_ATTR_REQUIRED"
	//   "INPUT_ATTR_STEP"
	//   "INPUT_TYPE_COLOR"
	//   "INPUT_TYPE_DATE"
	//   "INPUT_TYPE_DATETIME"
	//   "INPUT_TYPE_DATETIME_LOCAL"
	//   "INPUT_TYPE_EMAIL"
	//   "INPUT_TYPE_MONTH"
	//   "INPUT_TYPE_NUMBER"
	//   "INPUT_TYPE_RANGE"
	//   "INPUT_TYPE_SEARCH"
	//   "INPUT_TYPE_TEL"
	//   "INPUT_TYPE_TIME"
	//   "INPUT_TYPE_URL"
	//   "INPUT_TYPE_WEEK"
	//   "LOCAL_STORAGE"
	//   "POST_MESSAGE"
	//   "SESSION_STORAGE"
	//   "SMIL"
	//   "SVG_CLIP_PATHS"
	//   "SVG_FE_IMAGE"
	//   "SVG_FILTERS"
	//   "SVG_HREF"
	//   "TOUCH"
	//   "VIDEO"
	//   "WEBGL"
	//   "WEB_SOCKETS"
	//   "WEB_SQL_DATABASE"
	//   "WEB_WORKERS"
	DetectedFeatures []string `json:"detectedFeatures,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeAssetMetadata".
	Kind string `json:"kind,omitempty"`

	// WarnedValidationRules: Rules validated during code generation that
	// generated a warning. This is a read-only, auto-generated
	// field.
	//
	// Possible values are:
	// - "CLICK_TAG_NON_TOP_LEVEL"
	// - "CLICK_TAG_MISSING"
	// - "CLICK_TAG_MORE_THAN_ONE"
	// - "CLICK_TAG_INVALID"
	// - "ORPHANED_ASSET"
	// - "PRIMARY_HTML_MISSING"
	// - "EXTERNAL_FILE_REFERENCED"
	// - "MRAID_REFERENCED"
	// - "ADMOB_REFERENCED"
	// - "FILE_TYPE_INVALID"
	// - "ZIP_INVALID"
	// - "LINKED_FILE_NOT_FOUND"
	// - "MAX_FLASH_VERSION_11"
	// - "NOT_SSL_COMPLIANT"
	// - "FILE_DETAIL_EMPTY"
	// - "ASSET_INVALID"
	// - "GWD_PROPERTIES_INVALID"
	// - "ENABLER_UNSUPPORTED_METHOD_DCM"
	// - "ASSET_FORMAT_UNSUPPORTED_DCM"
	// - "COMPONENT_UNSUPPORTED_DCM"
	// - "HTML5_FEATURE_UNSUPPORTED' "
	//
	// Possible values:
	//   "ADMOB_REFERENCED"
	//   "ASSET_FORMAT_UNSUPPORTED_DCM"
	//   "ASSET_INVALID"
	//   "CLICK_TAG_HARD_CODED"
	//   "CLICK_TAG_INVALID"
	//   "CLICK_TAG_IN_GWD"
	//   "CLICK_TAG_MISSING"
	//   "CLICK_TAG_MORE_THAN_ONE"
	//   "CLICK_TAG_NON_TOP_LEVEL"
	//   "COMPONENT_UNSUPPORTED_DCM"
	//   "ENABLER_UNSUPPORTED_METHOD_DCM"
	//   "EXTERNAL_FILE_REFERENCED"
	//   "FILE_DETAIL_EMPTY"
	//   "FILE_TYPE_INVALID"
	//   "GWD_PROPERTIES_INVALID"
	//   "HTML5_FEATURE_UNSUPPORTED"
	//   "LINKED_FILE_NOT_FOUND"
	//   "MAX_FLASH_VERSION_11"
	//   "MRAID_REFERENCED"
	//   "NOT_SSL_COMPLIANT"
	//   "ORPHANED_ASSET"
	//   "PRIMARY_HTML_MISSING"
	//   "SVG_INVALID"
	//   "ZIP_INVALID"
	WarnedValidationRules []string `json:"warnedValidationRules,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AssetIdentifier") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeAssetMetadata) MarshalJSON() ([]byte, error) {
	type noMethod CreativeAssetMetadata
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeAssignment: Creative Assignment.
type CreativeAssignment struct {
	// Active: Whether this creative assignment is active. When true, the
	// creative will be included in the ad's rotation.
	Active bool `json:"active,omitempty"`

	// ApplyEventTags: Whether applicable event tags should fire when this
	// creative assignment is rendered. If this value is unset when the ad
	// is inserted or updated, it will default to true for all creative
	// types EXCEPT for INTERNAL_REDIRECT, INTERSTITIAL_INTERNAL_REDIRECT,
	// and INSTREAM_VIDEO.
	ApplyEventTags bool `json:"applyEventTags,omitempty"`

	// ClickThroughUrl: Click-through URL of the creative assignment.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// CompanionCreativeOverrides: Companion creative overrides for this
	// creative assignment. Applicable to video ads.
	CompanionCreativeOverrides []*CompanionClickThroughOverride `json:"companionCreativeOverrides,omitempty"`

	// CreativeGroupAssignments: Creative group assignments for this
	// creative assignment. Only one assignment per creative group number is
	// allowed for a maximum of two assignments.
	CreativeGroupAssignments []*CreativeGroupAssignment `json:"creativeGroupAssignments,omitempty"`

	// CreativeId: ID of the creative to be assigned. This is a required
	// field.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// CreativeIdDimensionValue: Dimension value for the ID of the creative.
	// This is a read-only, auto-generated field.
	CreativeIdDimensionValue *DimensionValue `json:"creativeIdDimensionValue,omitempty"`

	// EndTime: Date and time that the assigned creative should stop
	// serving. Must be later than the start time.
	EndTime string `json:"endTime,omitempty"`

	// RichMediaExitOverrides: Rich media exit overrides for this creative
	// assignment.
	// Applicable when the creative type is any of the following:
	// - RICH_MEDIA_INPAGE
	// - RICH_MEDIA_INPAGE_FLOATING
	// - RICH_MEDIA_IM_EXPAND
	// - RICH_MEDIA_EXPANDING
	// - RICH_MEDIA_INTERSTITIAL_FLOAT
	// - RICH_MEDIA_MOBILE_IN_APP
	// - RICH_MEDIA_MULTI_FLOATING
	// - RICH_MEDIA_PEEL_DOWN
	// - ADVANCED_BANNER
	// - VPAID_LINEAR
	// - VPAID_NON_LINEAR
	RichMediaExitOverrides []*RichMediaExitOverride `json:"richMediaExitOverrides,omitempty"`

	// Sequence: Sequence number of the creative assignment, applicable when
	// the rotation type is CREATIVE_ROTATION_TYPE_SEQUENTIAL.
	Sequence int64 `json:"sequence,omitempty"`

	// SslCompliant: Whether the creative to be assigned is SSL-compliant.
	// This is a read-only field that is auto-generated when the ad is
	// inserted or updated.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// StartTime: Date and time that the assigned creative should start
	// serving.
	StartTime string `json:"startTime,omitempty"`

	// Weight: Weight of the creative assignment, applicable when the
	// rotation type is CREATIVE_ROTATION_TYPE_RANDOM.
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Active") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeAssignment) MarshalJSON() ([]byte, error) {
	type noMethod CreativeAssignment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeCustomEvent: Creative Custom Event.
type CreativeCustomEvent struct {
	// Active: Whether the event is active.
	Active bool `json:"active,omitempty"`

	// AdvertiserCustomEventName: User-entered name for the event.
	AdvertiserCustomEventName string `json:"advertiserCustomEventName,omitempty"`

	// AdvertiserCustomEventType: Type of the event. This is a read-only
	// field.
	//
	// Possible values:
	//   "ADVERTISER_EVENT_COUNTER"
	//   "ADVERTISER_EVENT_EXIT"
	//   "ADVERTISER_EVENT_TIMER"
	AdvertiserCustomEventType string `json:"advertiserCustomEventType,omitempty"`

	// ArtworkLabel: Artwork label column, used to link events in DCM back
	// to events in Studio. This is a required field and should not be
	// modified after insertion.
	ArtworkLabel string `json:"artworkLabel,omitempty"`

	// ArtworkType: Artwork type used by the creative.This is a read-only
	// field.
	//
	// Possible values:
	//   "ARTWORK_TYPE_FLASH"
	//   "ARTWORK_TYPE_HTML5"
	//   "ARTWORK_TYPE_IMAGE"
	//   "ARTWORK_TYPE_MIXED"
	ArtworkType string `json:"artworkType,omitempty"`

	// ExitUrl: Exit URL of the event. This field is used only for exit
	// events.
	ExitUrl string `json:"exitUrl,omitempty"`

	// Id: ID of this event. This is a required field and should not be
	// modified after insertion.
	Id int64 `json:"id,omitempty,string"`

	// PopupWindowProperties: Properties for rich media popup windows. This
	// field is used only for exit events.
	PopupWindowProperties *PopupWindowProperties `json:"popupWindowProperties,omitempty"`

	// TargetType: Target type used by the event.
	//
	// Possible values:
	//   "TARGET_BLANK"
	//   "TARGET_PARENT"
	//   "TARGET_POPUP"
	//   "TARGET_SELF"
	//   "TARGET_TOP"
	TargetType string `json:"targetType,omitempty"`

	// VideoReportingId: Video reporting ID, used to differentiate multiple
	// videos in a single creative. This is a read-only field.
	VideoReportingId string `json:"videoReportingId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Active") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeCustomEvent) MarshalJSON() ([]byte, error) {
	type noMethod CreativeCustomEvent
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeField: Contains properties of a creative field.
type CreativeField struct {
	// AccountId: Account ID of this creative field. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this creative field. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Id: ID of this creative field. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeField".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this creative field. This is a required field and must
	// be less than 256 characters long and unique among creative fields of
	// the same advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this creative field. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeField) MarshalJSON() ([]byte, error) {
	type noMethod CreativeField
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeFieldAssignment: Creative Field Assignment.
type CreativeFieldAssignment struct {
	// CreativeFieldId: ID of the creative field.
	CreativeFieldId int64 `json:"creativeFieldId,omitempty,string"`

	// CreativeFieldValueId: ID of the creative field value.
	CreativeFieldValueId int64 `json:"creativeFieldValueId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "CreativeFieldId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeFieldAssignment) MarshalJSON() ([]byte, error) {
	type noMethod CreativeFieldAssignment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeFieldValue: Contains properties of a creative field value.
type CreativeFieldValue struct {
	// Id: ID of this creative field value. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldValue".
	Kind string `json:"kind,omitempty"`

	// Value: Value of this creative field value. It needs to be less than
	// 256 characters in length and unique per creative field.
	Value string `json:"value,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeFieldValue) MarshalJSON() ([]byte, error) {
	type noMethod CreativeFieldValue
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeFieldValuesListResponse: Creative Field Value List Response
type CreativeFieldValuesListResponse struct {
	// CreativeFieldValues: Creative field value collection.
	CreativeFieldValues []*CreativeFieldValue `json:"creativeFieldValues,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldValuesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreativeFieldValues")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeFieldValuesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CreativeFieldValuesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeFieldsListResponse: Creative Field List Response
type CreativeFieldsListResponse struct {
	// CreativeFields: Creative field collection.
	CreativeFields []*CreativeField `json:"creativeFields,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeFieldsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreativeFields") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeFieldsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CreativeFieldsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeGroup: Contains properties of a creative group.
type CreativeGroup struct {
	// AccountId: Account ID of this creative group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this creative group. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// GroupNumber: Subgroup of the creative group. Assign your creative
	// groups to one of the following subgroups in order to filter or manage
	// them more easily. This field is required on insertion and is
	// read-only after insertion.
	// Acceptable values are:
	// - 1
	// - 2
	GroupNumber int64 `json:"groupNumber,omitempty"`

	// Id: ID of this creative group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this creative group. This is a required field and must
	// be less than 256 characters long and unique among creative groups of
	// the same advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this creative group. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeGroup) MarshalJSON() ([]byte, error) {
	type noMethod CreativeGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeGroupAssignment: Creative Group Assignment.
type CreativeGroupAssignment struct {
	// CreativeGroupId: ID of the creative group to be assigned.
	CreativeGroupId int64 `json:"creativeGroupId,omitempty,string"`

	// CreativeGroupNumber: Creative group number of the creative group
	// assignment.
	//
	// Possible values:
	//   "CREATIVE_GROUP_ONE"
	//   "CREATIVE_GROUP_TWO"
	CreativeGroupNumber string `json:"creativeGroupNumber,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreativeGroupId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeGroupAssignment) MarshalJSON() ([]byte, error) {
	type noMethod CreativeGroupAssignment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeGroupsListResponse: Creative Group List Response
type CreativeGroupsListResponse struct {
	// CreativeGroups: Creative group collection.
	CreativeGroups []*CreativeGroup `json:"creativeGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativeGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "CreativeGroups") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CreativeGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeOptimizationConfiguration: Creative optimization settings.
type CreativeOptimizationConfiguration struct {
	// Id: ID of this creative optimization config. This field is
	// auto-generated when the campaign is inserted or updated. It can be
	// null for existing campaigns.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this creative optimization config. This is a required
	// field and must be less than 129 characters long.
	Name string `json:"name,omitempty"`

	// OptimizationActivitys: List of optimization activities associated
	// with this configuration.
	OptimizationActivitys []*OptimizationActivity `json:"optimizationActivitys,omitempty"`

	// OptimizationModel: Optimization model for this configuration.
	//
	// Possible values:
	//   "CLICK"
	//   "POST_CLICK"
	//   "POST_CLICK_AND_IMPRESSION"
	//   "POST_IMPRESSION"
	//   "VIDEO_COMPLETION"
	OptimizationModel string `json:"optimizationModel,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeOptimizationConfiguration) MarshalJSON() ([]byte, error) {
	type noMethod CreativeOptimizationConfiguration
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeRotation: Creative Rotation.
type CreativeRotation struct {
	// CreativeAssignments: Creative assignments in this creative rotation.
	CreativeAssignments []*CreativeAssignment `json:"creativeAssignments,omitempty"`

	// CreativeOptimizationConfigurationId: Creative optimization
	// configuration that is used by this ad. It should refer to one of the
	// existing optimization configurations in the ad's campaign. If it is
	// unset or set to 0, then the campaign's default optimization
	// configuration will be used for this ad.
	CreativeOptimizationConfigurationId int64 `json:"creativeOptimizationConfigurationId,omitempty,string"`

	// Type: Type of creative rotation. Can be used to specify whether to
	// use sequential or random rotation.
	//
	// Possible values:
	//   "CREATIVE_ROTATION_TYPE_RANDOM"
	//   "CREATIVE_ROTATION_TYPE_SEQUENTIAL"
	Type string `json:"type,omitempty"`

	// WeightCalculationStrategy: Strategy for calculating weights. Used
	// with CREATIVE_ROTATION_TYPE_RANDOM.
	//
	// Possible values:
	//   "WEIGHT_STRATEGY_CUSTOM"
	//   "WEIGHT_STRATEGY_EQUAL"
	//   "WEIGHT_STRATEGY_HIGHEST_CTR"
	//   "WEIGHT_STRATEGY_OPTIMIZED"
	WeightCalculationStrategy string `json:"weightCalculationStrategy,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CreativeAssignments")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeRotation) MarshalJSON() ([]byte, error) {
	type noMethod CreativeRotation
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativeSettings: Creative Settings
type CreativeSettings struct {
	// IFrameFooter: Header text for iFrames for this site. Must be less
	// than or equal to 2000 characters long.
	IFrameFooter string `json:"iFrameFooter,omitempty"`

	// IFrameHeader: Header text for iFrames for this site. Must be less
	// than or equal to 2000 characters long.
	IFrameHeader string `json:"iFrameHeader,omitempty"`

	// ForceSendFields is a list of field names (e.g. "IFrameFooter") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativeSettings) MarshalJSON() ([]byte, error) {
	type noMethod CreativeSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CreativesListResponse: Creative List Response
type CreativesListResponse struct {
	// Creatives: Creative collection.
	Creatives []*Creative `json:"creatives,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#creativesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Creatives") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CreativesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod CreativesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CrossDimensionReachReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type
// "CROSS_DIMENSION_REACH".
type CrossDimensionReachReportCompatibleFields struct {
	// Breakdown: Dimensions which are compatible to be selected in the
	// "breakdown" section of the report.
	Breakdown []*Dimension `json:"breakdown,omitempty"`

	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#crossDimensionReachReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// OverlapMetrics: Metrics which are compatible to be selected in the
	// "overlapMetricNames" section of the report.
	OverlapMetrics []*Metric `json:"overlapMetrics,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Breakdown") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CrossDimensionReachReportCompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod CrossDimensionReachReportCompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// CustomRichMediaEvents: Represents a Custom Rich Media Events group.
type CustomRichMediaEvents struct {
	// FilteredEventIds: List of custom rich media event IDs. Dimension
	// values must be all of type dfa:richMediaEventTypeIdAndName.
	FilteredEventIds []*DimensionValue `json:"filteredEventIds,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#customRichMediaEvents.
	Kind string `json:"kind,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FilteredEventIds") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *CustomRichMediaEvents) MarshalJSON() ([]byte, error) {
	type noMethod CustomRichMediaEvents
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DateRange: Represents a date range.
type DateRange struct {
	// EndDate: The end date of the date range, inclusive. A string of the
	// format: "yyyy-MM-dd".
	EndDate string `json:"endDate,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dateRange.
	Kind string `json:"kind,omitempty"`

	// RelativeDateRange: The date range relative to the date of when the
	// report is run.
	//
	// Possible values:
	//   "LAST_24_MONTHS"
	//   "LAST_30_DAYS"
	//   "LAST_365_DAYS"
	//   "LAST_7_DAYS"
	//   "LAST_90_DAYS"
	//   "MONTH_TO_DATE"
	//   "PREVIOUS_MONTH"
	//   "PREVIOUS_QUARTER"
	//   "PREVIOUS_WEEK"
	//   "PREVIOUS_YEAR"
	//   "QUARTER_TO_DATE"
	//   "TODAY"
	//   "WEEK_TO_DATE"
	//   "YEAR_TO_DATE"
	//   "YESTERDAY"
	RelativeDateRange string `json:"relativeDateRange,omitempty"`

	// StartDate: The start date of the date range, inclusive. A string of
	// the format: "yyyy-MM-dd".
	StartDate string `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EndDate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DateRange) MarshalJSON() ([]byte, error) {
	type noMethod DateRange
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DayPartTargeting: Day Part Targeting.
type DayPartTargeting struct {
	// DaysOfWeek: Days of the week when the ad will serve.
	//
	// Acceptable values are:
	// - "SUNDAY"
	// - "MONDAY"
	// - "TUESDAY"
	// - "WEDNESDAY"
	// - "THURSDAY"
	// - "FRIDAY"
	// - "SATURDAY"
	//
	// Possible values:
	//   "FRIDAY"
	//   "MONDAY"
	//   "SATURDAY"
	//   "SUNDAY"
	//   "THURSDAY"
	//   "TUESDAY"
	//   "WEDNESDAY"
	DaysOfWeek []string `json:"daysOfWeek,omitempty"`

	// HoursOfDay: Hours of the day when the ad will serve. Must be an
	// integer between 0 and 23 (inclusive), where 0 is midnight to 1 AM,
	// and 23 is 11 PM to midnight. Can be specified with days of week, in
	// which case the ad would serve during these hours on the specified
	// days. For example, if Monday, Wednesday, Friday are the days of week
	// specified and 9-10am, 3-5pm (hours 9, 15, and 16) is specified, the
	// ad would serve Monday, Wednesdays, and Fridays at 9-10am and 3-5pm.
	HoursOfDay []int64 `json:"hoursOfDay,omitempty"`

	// UserLocalTime: Whether or not to use the user's local time. If false,
	// the America/New York time zone applies.
	UserLocalTime bool `json:"userLocalTime,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DaysOfWeek") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DayPartTargeting) MarshalJSON() ([]byte, error) {
	type noMethod DayPartTargeting
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DefaultClickThroughEventTagProperties: Properties of inheriting and
// overriding the default click-through event tag. A campaign may
// override the event tag defined at the advertiser level, and an ad may
// also override the campaign's setting further.
type DefaultClickThroughEventTagProperties struct {
	// DefaultClickThroughEventTagId: ID of the click-through event tag to
	// apply to all ads in this entity's scope.
	DefaultClickThroughEventTagId int64 `json:"defaultClickThroughEventTagId,omitempty,string"`

	// OverrideInheritedEventTag: Whether this entity should override the
	// inherited default click-through event tag with its own defined value.
	OverrideInheritedEventTag bool `json:"overrideInheritedEventTag,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "DefaultClickThroughEventTagId") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DefaultClickThroughEventTagProperties) MarshalJSON() ([]byte, error) {
	type noMethod DefaultClickThroughEventTagProperties
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DeliverySchedule: Delivery Schedule.
type DeliverySchedule struct {
	// FrequencyCap: Limit on the number of times an individual user can be
	// served the ad within a specified period of time.
	FrequencyCap *FrequencyCap `json:"frequencyCap,omitempty"`

	// HardCutoff: Whether or not hard cutoff is enabled. If true, the ad
	// will not serve after the end date and time. Otherwise the ad will
	// continue to be served until it has reached its delivery goals.
	HardCutoff bool `json:"hardCutoff,omitempty"`

	// ImpressionRatio: Impression ratio for this ad. This ratio determines
	// how often each ad is served relative to the others. For example, if
	// ad A has an impression ratio of 1 and ad B has an impression ratio of
	// 3, then DCM will serve ad B three times as often as ad A. Must be
	// between 1 and 10.
	ImpressionRatio int64 `json:"impressionRatio,omitempty,string"`

	// Priority: Serving priority of an ad, with respect to other ads. The
	// lower the priority number, the greater the priority with which it is
	// served.
	//
	// Possible values:
	//   "AD_PRIORITY_01"
	//   "AD_PRIORITY_02"
	//   "AD_PRIORITY_03"
	//   "AD_PRIORITY_04"
	//   "AD_PRIORITY_05"
	//   "AD_PRIORITY_06"
	//   "AD_PRIORITY_07"
	//   "AD_PRIORITY_08"
	//   "AD_PRIORITY_09"
	//   "AD_PRIORITY_10"
	//   "AD_PRIORITY_11"
	//   "AD_PRIORITY_12"
	//   "AD_PRIORITY_13"
	//   "AD_PRIORITY_14"
	//   "AD_PRIORITY_15"
	//   "AD_PRIORITY_16"
	Priority string `json:"priority,omitempty"`

	// ForceSendFields is a list of field names (e.g. "FrequencyCap") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DeliverySchedule) MarshalJSON() ([]byte, error) {
	type noMethod DeliverySchedule
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DfpSettings: DFP Settings
type DfpSettings struct {
	// DfpNetworkCode: DFP network code for this directory site.
	DfpNetworkCode string `json:"dfp_network_code,omitempty"`

	// DfpNetworkName: DFP network name for this directory site.
	DfpNetworkName string `json:"dfp_network_name,omitempty"`

	// ProgrammaticPlacementAccepted: Whether this directory site accepts
	// programmatic placements.
	ProgrammaticPlacementAccepted bool `json:"programmaticPlacementAccepted,omitempty"`

	// PubPaidPlacementAccepted: Whether this directory site accepts
	// publisher-paid tags.
	PubPaidPlacementAccepted bool `json:"pubPaidPlacementAccepted,omitempty"`

	// PublisherPortalOnly: Whether this directory site is available only
	// via DoubleClick Publisher Portal.
	PublisherPortalOnly bool `json:"publisherPortalOnly,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DfpNetworkCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DfpSettings) MarshalJSON() ([]byte, error) {
	type noMethod DfpSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Dimension: Represents a dimension.
type Dimension struct {
	// Kind: The kind of resource this is, in this case
	// dfareporting#dimension.
	Kind string `json:"kind,omitempty"`

	// Name: The dimension name, e.g. dfa:advertiser
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Dimension) MarshalJSON() ([]byte, error) {
	type noMethod Dimension
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DimensionFilter: Represents a dimension filter.
type DimensionFilter struct {
	// DimensionName: The name of the dimension to filter.
	DimensionName string `json:"dimensionName,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dimensionFilter.
	Kind string `json:"kind,omitempty"`

	// Value: The value of the dimension to filter.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DimensionFilter) MarshalJSON() ([]byte, error) {
	type noMethod DimensionFilter
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DimensionValue: Represents a DimensionValue resource.
type DimensionValue struct {
	// DimensionName: The name of the dimension.
	DimensionName string `json:"dimensionName,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Id: The ID associated with the value if available.
	Id string `json:"id,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#dimensionValue.
	Kind string `json:"kind,omitempty"`

	// MatchType: Determines how the 'value' field is matched when
	// filtering. If not specified, defaults to EXACT. If set to
	// WILDCARD_EXPRESSION, '*' is allowed as a placeholder for variable
	// length character sequences, and it can be escaped with a backslash.
	// Note, only paid search dimensions ('dfa:paidSearch*') allow a
	// matchType other than EXACT.
	//
	// Possible values:
	//   "BEGINS_WITH"
	//   "CONTAINS"
	//   "EXACT"
	//   "WILDCARD_EXPRESSION"
	MatchType string `json:"matchType,omitempty"`

	// Value: The value of the dimension.
	Value string `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DimensionValue) MarshalJSON() ([]byte, error) {
	type noMethod DimensionValue
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DimensionValueList: Represents the list of DimensionValue resources.
type DimensionValueList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The dimension values returned in this response.
	Items []*DimensionValue `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case
	// dfareporting#dimensionValueList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through dimension
	// values. To retrieve the next page of results, set the next request's
	// "pageToken" to the value of this field. The page token is only valid
	// for a limited amount of time and should not be persisted.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DimensionValueList) MarshalJSON() ([]byte, error) {
	type noMethod DimensionValueList
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DimensionValueRequest: Represents a DimensionValuesRequest.
type DimensionValueRequest struct {
	// DimensionName: The name of the dimension for which values should be
	// requested.
	DimensionName string `json:"dimensionName,omitempty"`

	// EndDate: The end date of the date range for which to retrieve
	// dimension values. A string of the format "yyyy-MM-dd".
	EndDate string `json:"endDate,omitempty"`

	// Filters: The list of filters by which to filter values. The filters
	// are ANDed.
	Filters []*DimensionFilter `json:"filters,omitempty"`

	// Kind: The kind of request this is, in this case
	// dfareporting#dimensionValueRequest.
	Kind string `json:"kind,omitempty"`

	// StartDate: The start date of the date range for which to retrieve
	// dimension values. A string of the format "yyyy-MM-dd".
	StartDate string `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionName") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DimensionValueRequest) MarshalJSON() ([]byte, error) {
	type noMethod DimensionValueRequest
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySite: DirectorySites contains properties of a website from
// the Site Directory. Sites need to be added to an account via the
// Sites resource before they can be assigned to a placement.
type DirectorySite struct {
	// Active: Whether this directory site is active.
	Active bool `json:"active,omitempty"`

	// ContactAssignments: Directory site contacts.
	ContactAssignments []*DirectorySiteContactAssignment `json:"contactAssignments,omitempty"`

	// CountryId: Country ID of this directory site.
	CountryId int64 `json:"countryId,omitempty,string"`

	// CurrencyId: Currency ID of this directory site.
	// Possible values are:
	// - "1" for USD
	// - "2" for GBP
	// - "3" for ESP
	// - "4" for SEK
	// - "5" for CAD
	// - "6" for JPY
	// - "7" for DEM
	// - "8" for AUD
	// - "9" for FRF
	// - "10" for ITL
	// - "11" for DKK
	// - "12" for NOK
	// - "13" for FIM
	// - "14" for ZAR
	// - "15" for IEP
	// - "16" for NLG
	// - "17" for EUR
	// - "18" for KRW
	// - "19" for TWD
	// - "20" for SGD
	// - "21" for CNY
	// - "22" for HKD
	// - "23" for NZD
	// - "24" for MYR
	// - "25" for BRL
	// - "26" for PTE
	// - "27" for MXP
	// - "28" for CLP
	// - "29" for TRY
	// - "30" for ARS
	// - "31" for PEN
	// - "32" for ILS
	// - "33" for CHF
	// - "34" for VEF
	// - "35" for COP
	// - "36" for GTQ
	// - "37" for PLN
	// - "39" for INR
	// - "40" for THB
	// - "41" for IDR
	// - "42" for CZK
	// - "43" for RON
	// - "44" for HUF
	// - "45" for RUB
	// - "46" for AED
	// - "47" for BGN
	// - "48" for HRK
	CurrencyId int64 `json:"currencyId,omitempty,string"`

	// Description: Description of this directory site.
	Description string `json:"description,omitempty"`

	// Id: ID of this directory site. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this directory site.
	// This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// InpageTagFormats: Tag types for regular placements.
	//
	// Acceptable values are:
	// - "STANDARD"
	// - "IFRAME_JAVASCRIPT_INPAGE"
	// - "INTERNAL_REDIRECT_INPAGE"
	// - "JAVASCRIPT_INPAGE"
	//
	// Possible values:
	//   "IFRAME_JAVASCRIPT_INPAGE"
	//   "INTERNAL_REDIRECT_INPAGE"
	//   "JAVASCRIPT_INPAGE"
	//   "STANDARD"
	InpageTagFormats []string `json:"inpageTagFormats,omitempty"`

	// InterstitialTagFormats: Tag types for interstitial
	// placements.
	//
	// Acceptable values are:
	// - "IFRAME_JAVASCRIPT_INTERSTITIAL"
	// - "INTERNAL_REDIRECT_INTERSTITIAL"
	// - "JAVASCRIPT_INTERSTITIAL"
	//
	// Possible values:
	//   "IFRAME_JAVASCRIPT_INTERSTITIAL"
	//   "INTERNAL_REDIRECT_INTERSTITIAL"
	//   "JAVASCRIPT_INTERSTITIAL"
	InterstitialTagFormats []string `json:"interstitialTagFormats,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySite".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this directory site.
	Name string `json:"name,omitempty"`

	// ParentId: Parent directory site ID.
	ParentId int64 `json:"parentId,omitempty,string"`

	// Settings: Directory site settings.
	Settings *DirectorySiteSettings `json:"settings,omitempty"`

	// Url: URL of this directory site.
	Url string `json:"url,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Active") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySite) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySite
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySiteContact: Contains properties of a Site Directory
// contact.
type DirectorySiteContact struct {
	// Email: Email address of this directory site contact.
	Email string `json:"email,omitempty"`

	// FirstName: First name of this directory site contact.
	FirstName string `json:"firstName,omitempty"`

	// Id: ID of this directory site contact. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySiteContact".
	Kind string `json:"kind,omitempty"`

	// LastName: Last name of this directory site contact.
	LastName string `json:"lastName,omitempty"`

	// Role: Directory site contact role.
	//
	// Possible values:
	//   "ADMIN"
	//   "EDIT"
	//   "VIEW"
	Role string `json:"role,omitempty"`

	// Type: Directory site contact type.
	//
	// Possible values:
	//   "BILLING"
	//   "OTHER"
	//   "SALES"
	//   "TECHNICAL"
	Type string `json:"type,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Email") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySiteContact) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySiteContact
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySiteContactAssignment: Directory Site Contact Assignment
type DirectorySiteContactAssignment struct {
	// ContactId: ID of this directory site contact. This is a read-only,
	// auto-generated field.
	ContactId int64 `json:"contactId,omitempty,string"`

	// Visibility: Visibility of this directory site contact assignment.
	// When set to PUBLIC this contact assignment is visible to all account
	// and agency users; when set to PRIVATE it is visible only to the site.
	//
	// Possible values:
	//   "PRIVATE"
	//   "PUBLIC"
	Visibility string `json:"visibility,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContactId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySiteContactAssignment) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySiteContactAssignment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySiteContactsListResponse: Directory Site Contact List
// Response
type DirectorySiteContactsListResponse struct {
	// DirectorySiteContacts: Directory site contact collection
	DirectorySiteContacts []*DirectorySiteContact `json:"directorySiteContacts,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySiteContactsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "DirectorySiteContacts") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySiteContactsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySiteContactsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySiteSettings: Directory Site Settings
type DirectorySiteSettings struct {
	// ActiveViewOptOut: Whether this directory site has disabled active
	// view creatives.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// DfpSettings: Directory site DFP settings.
	DfpSettings *DfpSettings `json:"dfp_settings,omitempty"`

	// InstreamVideoPlacementAccepted: Whether this site accepts in-stream
	// video ads.
	InstreamVideoPlacementAccepted bool `json:"instream_video_placement_accepted,omitempty"`

	// InterstitialPlacementAccepted: Whether this site accepts interstitial
	// ads.
	InterstitialPlacementAccepted bool `json:"interstitialPlacementAccepted,omitempty"`

	// NielsenOcrOptOut: Whether this directory site has disabled Nielsen
	// OCR reach ratings.
	NielsenOcrOptOut bool `json:"nielsenOcrOptOut,omitempty"`

	// VerificationTagOptOut: Whether this directory site has disabled
	// generation of Verification ins tags.
	VerificationTagOptOut bool `json:"verificationTagOptOut,omitempty"`

	// VideoActiveViewOptOut: Whether this directory site has disabled
	// active view for in-stream video creatives.
	VideoActiveViewOptOut bool `json:"videoActiveViewOptOut,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActiveViewOptOut") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySiteSettings) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySiteSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// DirectorySitesListResponse: Directory Site List Response
type DirectorySitesListResponse struct {
	// DirectorySites: Directory site collection.
	DirectorySites []*DirectorySite `json:"directorySites,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#directorySitesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "DirectorySites") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *DirectorySitesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod DirectorySitesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// EventTag: Contains properties of an event tag.
type EventTag struct {
	// AccountId: Account ID of this event tag. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this event tag. This field or the
	// campaignId field is required on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// CampaignId: Campaign ID of this event tag. This field or the
	// advertiserId field is required on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// EnabledByDefault: Whether this event tag should be automatically
	// enabled for all of the advertiser's campaigns and ads.
	EnabledByDefault bool `json:"enabledByDefault,omitempty"`

	// Id: ID of this event tag. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#eventTag".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this event tag. This is a required field and must be
	// less than 256 characters long.
	Name string `json:"name,omitempty"`

	// SiteFilterType: Site filter type for this event tag. If no type is
	// specified then the event tag will be applied to all sites.
	//
	// Possible values:
	//   "BLACKLIST"
	//   "WHITELIST"
	SiteFilterType string `json:"siteFilterType,omitempty"`

	// SiteIds: Filter list of site IDs associated with this event tag. The
	// siteFilterType determines whether this is a whitelist or blacklist
	// filter.
	SiteIds googleapi.Int64s `json:"siteIds,omitempty"`

	// SslCompliant: Whether this tag is SSL-compliant or not. This is a
	// read-only field.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// Status: Status of this event tag. Must be ENABLED for this event tag
	// to fire. This is a required field.
	//
	// Possible values:
	//   "DISABLED"
	//   "ENABLED"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this event tag. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Type: Event tag type. Can be used to specify whether to use a
	// third-party pixel, a third-party JavaScript URL, or a third-party
	// click-through URL for either impression or click tracking. This is a
	// required field.
	//
	// Possible values:
	//   "CLICK_THROUGH_EVENT_TAG"
	//   "IMPRESSION_IMAGE_EVENT_TAG"
	//   "IMPRESSION_JAVASCRIPT_EVENT_TAG"
	Type string `json:"type,omitempty"`

	// Url: Payload URL for this event tag. The URL on a click-through event
	// tag should have a landing page URL appended to the end of it. This
	// field is required on insertion.
	Url string `json:"url,omitempty"`

	// UrlEscapeLevels: Number of times the landing page URL should be
	// URL-escaped before being appended to the click-through event tag URL.
	// Only applies to click-through event tags as specified by the event
	// tag type.
	UrlEscapeLevels int64 `json:"urlEscapeLevels,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *EventTag) MarshalJSON() ([]byte, error) {
	type noMethod EventTag
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// EventTagOverride: Event tag override information.
type EventTagOverride struct {
	// Enabled: Whether this override is enabled.
	Enabled bool `json:"enabled,omitempty"`

	// Id: ID of this event tag override. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Enabled") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *EventTagOverride) MarshalJSON() ([]byte, error) {
	type noMethod EventTagOverride
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// EventTagsListResponse: Event Tag List Response
type EventTagsListResponse struct {
	// EventTags: Event tag collection.
	EventTags []*EventTag `json:"eventTags,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#eventTagsListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "EventTags") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *EventTagsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod EventTagsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// File: Represents a File resource. A file contains the metadata for a
// report run. It shows the status of the run and holds the URLs to the
// generated report data if the run is finished and the status is
// "REPORT_AVAILABLE".
type File struct {
	// DateRange: The date range for which the file has report data. The
	// date range will always be the absolute date range for which the
	// report is run.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// FileName: The filename of the file.
	FileName string `json:"fileName,omitempty"`

	// Format: The output format of the report. Only available once the file
	// is available.
	//
	// Possible values:
	//   "CSV"
	//   "EXCEL"
	Format string `json:"format,omitempty"`

	// Id: The unique ID of this report file.
	Id int64 `json:"id,omitempty,string"`

	// Kind: The kind of resource this is, in this case dfareporting#file.
	Kind string `json:"kind,omitempty"`

	// LastModifiedTime: The timestamp in milliseconds since epoch when this
	// file was last modified.
	LastModifiedTime int64 `json:"lastModifiedTime,omitempty,string"`

	// ReportId: The ID of the report this file was generated from.
	ReportId int64 `json:"reportId,omitempty,string"`

	// Status: The status of the report file.
	//
	// Possible values:
	//   "CANCELLED"
	//   "FAILED"
	//   "PROCESSING"
	//   "REPORT_AVAILABLE"
	Status string `json:"status,omitempty"`

	// Urls: The URLs where the completed report file can be downloaded.
	Urls *FileUrls `json:"urls,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "DateRange") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *File) MarshalJSON() ([]byte, error) {
	type noMethod File
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FileUrls: The URLs where the completed report file can be downloaded.
type FileUrls struct {
	// ApiUrl: The URL for downloading the report data through the API.
	ApiUrl string `json:"apiUrl,omitempty"`

	// BrowserUrl: The URL for downloading the report data through a
	// browser.
	BrowserUrl string `json:"browserUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ApiUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FileUrls) MarshalJSON() ([]byte, error) {
	type noMethod FileUrls
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FileList: Represents the list of File resources.
type FileList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The files returned in this response.
	Items []*File `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case dfareporting#fileList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through files. To
	// retrieve the next page of results, set the next request's "pageToken"
	// to the value of this field. The page token is only valid for a
	// limited amount of time and should not be persisted.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FileList) MarshalJSON() ([]byte, error) {
	type noMethod FileList
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivitiesGenerateTagResponse: Floodlight Activity
// GenerateTag Response
type FloodlightActivitiesGenerateTagResponse struct {
	// FloodlightActivityTag: Generated tag for this floodlight activity.
	FloodlightActivityTag string `json:"floodlightActivityTag,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivitiesGenerateTagResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivityTag") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivitiesGenerateTagResponse) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivitiesGenerateTagResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivitiesListResponse: Floodlight Activity List Response
type FloodlightActivitiesListResponse struct {
	// FloodlightActivities: Floodlight activity collection.
	FloodlightActivities []*FloodlightActivity `json:"floodlightActivities,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivitiesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivities") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivitiesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivitiesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivity: Contains properties of a Floodlight activity.
type FloodlightActivity struct {
	// AccountId: Account ID of this floodlight activity. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this floodlight activity. If this
	// field is left blank, the value will be copied over either from the
	// activity group's advertiser or the existing activity's advertiser.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// CacheBustingType: Code type used for cache busting in the generated
	// tag.
	//
	// Possible values:
	//   "ACTIVE_SERVER_PAGE"
	//   "COLD_FUSION"
	//   "JAVASCRIPT"
	//   "JSP"
	//   "PHP"
	CacheBustingType string `json:"cacheBustingType,omitempty"`

	// CountingMethod: Counting method for conversions for this floodlight
	// activity. This is a required field.
	//
	// Possible values:
	//   "ITEMS_SOLD_COUNTING"
	//   "SESSION_COUNTING"
	//   "STANDARD_COUNTING"
	//   "TRANSACTIONS_COUNTING"
	//   "UNIQUE_COUNTING"
	CountingMethod string `json:"countingMethod,omitempty"`

	// DefaultTags: Dynamic floodlight tags.
	DefaultTags []*FloodlightActivityDynamicTag `json:"defaultTags,omitempty"`

	// ExpectedUrl: URL where this tag will be deployed. If specified, must
	// be less than 256 characters long.
	ExpectedUrl string `json:"expectedUrl,omitempty"`

	// FloodlightActivityGroupId: Floodlight activity group ID of this
	// floodlight activity. This is a required field.
	FloodlightActivityGroupId int64 `json:"floodlightActivityGroupId,omitempty,string"`

	// FloodlightActivityGroupName: Name of the associated floodlight
	// activity group. This is a read-only field.
	FloodlightActivityGroupName string `json:"floodlightActivityGroupName,omitempty"`

	// FloodlightActivityGroupTagString: Tag string of the associated
	// floodlight activity group. This is a read-only field.
	FloodlightActivityGroupTagString string `json:"floodlightActivityGroupTagString,omitempty"`

	// FloodlightActivityGroupType: Type of the associated floodlight
	// activity group. This is a read-only field.
	//
	// Possible values:
	//   "COUNTER"
	//   "SALE"
	FloodlightActivityGroupType string `json:"floodlightActivityGroupType,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// floodlight activity. If this field is left blank, the value will be
	// copied over either from the activity group's floodlight configuration
	// or from the existing activity's floodlight configuration.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// Hidden: Whether this activity is archived.
	Hidden bool `json:"hidden,omitempty"`

	// Id: ID of this floodlight activity. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// activity. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// ImageTagEnabled: Whether the image tag is enabled for this activity.
	ImageTagEnabled bool `json:"imageTagEnabled,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivity".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this floodlight activity. This is a required field.
	// Must be less than 129 characters long and cannot contain quotes.
	Name string `json:"name,omitempty"`

	// Notes: General notes or implementation instructions for the tag.
	Notes string `json:"notes,omitempty"`

	// PublisherTags: Publisher dynamic floodlight tags.
	PublisherTags []*FloodlightActivityPublisherDynamicTag `json:"publisherTags,omitempty"`

	// Secure: Whether this tag should use SSL.
	Secure bool `json:"secure,omitempty"`

	// SslCompliant: Whether the floodlight activity is SSL-compliant. This
	// is a read-only field, its value detected by the system from the
	// floodlight tags.
	SslCompliant bool `json:"sslCompliant,omitempty"`

	// SslRequired: Whether this floodlight activity must be SSL-compliant.
	SslRequired bool `json:"sslRequired,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight activity. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagFormat: Tag format type for the floodlight activity. If left
	// blank, the tag format will default to HTML.
	//
	// Possible values:
	//   "HTML"
	//   "XHTML"
	TagFormat string `json:"tagFormat,omitempty"`

	// TagString: Value of the cat= paramter in the floodlight tag, which
	// the ad servers use to identify the activity. This is optional: if
	// empty, a new tag string will be generated for you. This string must
	// be 1 to 8 characters long, with valid characters being
	// [a-z][A-Z][0-9][-][ _ ]. This tag string must also be unique among
	// activities of the same activity group. This field is read-only after
	// insertion.
	TagString string `json:"tagString,omitempty"`

	// UserDefinedVariableTypes: List of the user-defined variables used by
	// this conversion tag. These map to the "u[1-20]=" in the tags. Each of
	// these can have a user defined type.
	// Acceptable values are:
	// - "U1"
	// - "U2"
	// - "U3"
	// - "U4"
	// - "U5"
	// - "U6"
	// - "U7"
	// - "U8"
	// - "U9"
	// - "U10"
	// - "U11"
	// - "U12"
	// - "U13"
	// - "U14"
	// - "U15"
	// - "U16"
	// - "U17"
	// - "U18"
	// - "U19"
	// - "U20"
	//
	// Possible values:
	//   "U1"
	//   "U10"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U2"
	//   "U20"
	//   "U3"
	//   "U4"
	//   "U5"
	//   "U6"
	//   "U7"
	//   "U8"
	//   "U9"
	UserDefinedVariableTypes []string `json:"userDefinedVariableTypes,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivity) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivity
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivityDynamicTag: Dynamic Tag
type FloodlightActivityDynamicTag struct {
	// Id: ID of this dynamic tag. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Name: Name of this tag.
	Name string `json:"name,omitempty"`

	// Tag: Tag code.
	Tag string `json:"tag,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivityDynamicTag) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivityDynamicTag
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivityGroup: Contains properties of a Floodlight activity
// group.
type FloodlightActivityGroup struct {
	// AccountId: Account ID of this floodlight activity group. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this floodlight activity group. If
	// this field is left blank, the value will be copied over either from
	// the floodlight configuration's advertiser or from the existing
	// activity group's advertiser.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// FloodlightConfigurationId: Floodlight configuration ID of this
	// floodlight activity group. This is a required field.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

	// FloodlightConfigurationIdDimensionValue: Dimension value for the ID
	// of the floodlight configuration. This is a read-only, auto-generated
	// field.
	FloodlightConfigurationIdDimensionValue *DimensionValue `json:"floodlightConfigurationIdDimensionValue,omitempty"`

	// Id: ID of this floodlight activity group. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// activity group. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivityGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this floodlight activity group. This is a required
	// field. Must be less than 65 characters long and cannot contain
	// quotes.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight activity group. This
	// is a read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagString: Value of the type= parameter in the floodlight tag, which
	// the ad servers use to identify the activity group that the activity
	// belongs to. This is optional: if empty, a new tag string will be
	// generated for you. This string must be 1 to 8 characters long, with
	// valid characters being [a-z][A-Z][0-9][-][ _ ]. This tag string must
	// also be unique among activity groups of the same floodlight
	// configuration. This field is read-only after insertion.
	TagString string `json:"tagString,omitempty"`

	// Type: Type of the floodlight activity group. This is a required field
	// that is read-only after insertion.
	//
	// Possible values:
	//   "COUNTER"
	//   "SALE"
	Type string `json:"type,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivityGroup) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivityGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivityGroupsListResponse: Floodlight Activity Group List
// Response
type FloodlightActivityGroupsListResponse struct {
	// FloodlightActivityGroups: Floodlight activity group collection.
	FloodlightActivityGroups []*FloodlightActivityGroup `json:"floodlightActivityGroups,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightActivityGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivityGroups") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivityGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivityGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightActivityPublisherDynamicTag: Publisher Dynamic Tag
type FloodlightActivityPublisherDynamicTag struct {
	// ClickThrough: Whether this tag is applicable only for click-throughs.
	ClickThrough bool `json:"clickThrough,omitempty"`

	// DirectorySiteId: Directory site ID of this dynamic tag. This is a
	// write-only field that can be used as an alternative to the siteId
	// field. When this resource is retrieved, only the siteId field will be
	// populated.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DynamicTag: Dynamic floodlight tag.
	DynamicTag *FloodlightActivityDynamicTag `json:"dynamicTag,omitempty"`

	// SiteId: Site ID of this dynamic tag.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// ViewThrough: Whether this tag is applicable only for view-throughs.
	ViewThrough bool `json:"viewThrough,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ClickThrough") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightActivityPublisherDynamicTag) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightActivityPublisherDynamicTag
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightConfiguration: Contains properties of a Floodlight
// configuration.
type FloodlightConfiguration struct {
	// AccountId: Account ID of this floodlight configuration. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of the parent advertiser of this
	// floodlight configuration.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// AnalyticsDataSharingEnabled: Whether advertiser data is shared with
	// Google Analytics.
	AnalyticsDataSharingEnabled bool `json:"analyticsDataSharingEnabled,omitempty"`

	// ExposureToConversionEnabled: Whether the exposure-to-conversion
	// report is enabled. This report shows detailed pathway information on
	// up to 10 of the most recent ad exposures seen by a user before
	// converting.
	ExposureToConversionEnabled bool `json:"exposureToConversionEnabled,omitempty"`

	// FirstDayOfWeek: Day that will be counted as the first day of the week
	// in reports. This is a required field.
	//
	// Possible values:
	//   "MONDAY"
	//   "SUNDAY"
	FirstDayOfWeek string `json:"firstDayOfWeek,omitempty"`

	// Id: ID of this floodlight configuration. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this floodlight
	// configuration. This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightConfiguration".
	Kind string `json:"kind,omitempty"`

	// LookbackConfiguration: Lookback window settings for this floodlight
	// configuration.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// NaturalSearchConversionAttributionOption: Types of attribution
	// options for natural search conversions.
	//
	// Possible values:
	//   "EXCLUDE_NATURAL_SEARCH_CONVERSION_ATTRIBUTION"
	//   "INCLUDE_NATURAL_SEARCH_CONVERSION_ATTRIBUTION"
	//   "INCLUDE_NATURAL_SEARCH_TIERED_CONVERSION_ATTRIBUTION"
	NaturalSearchConversionAttributionOption string `json:"naturalSearchConversionAttributionOption,omitempty"`

	// OmnitureSettings: Settings for DCM Omniture integration.
	OmnitureSettings *OmnitureSettings `json:"omnitureSettings,omitempty"`

	// SslRequired: Whether floodlight activities owned by this
	// configuration are required to be SSL-compliant.
	SslRequired bool `json:"sslRequired,omitempty"`

	// StandardVariableTypes: List of standard variables enabled for this
	// configuration.
	//
	// Acceptable values are:
	// - "ORD"
	// - "NUM"
	//
	// Possible values:
	//   "NUM"
	//   "ORD"
	//   "TRAN"
	//   "U"
	StandardVariableTypes []string `json:"standardVariableTypes,omitempty"`

	// SubaccountId: Subaccount ID of this floodlight configuration. This is
	// a read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagSettings: Configuration settings for dynamic and image floodlight
	// tags.
	TagSettings *TagSettings `json:"tagSettings,omitempty"`

	// UserDefinedVariableConfigurations: List of user defined variables
	// enabled for this configuration.
	UserDefinedVariableConfigurations []*UserDefinedVariableConfiguration `json:"userDefinedVariableConfigurations,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightConfiguration) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightConfiguration
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightConfigurationsListResponse: Floodlight Configuration List
// Response
type FloodlightConfigurationsListResponse struct {
	// FloodlightConfigurations: Floodlight configuration collection.
	FloodlightConfigurations []*FloodlightConfiguration `json:"floodlightConfigurations,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#floodlightConfigurationsListResponse".
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightConfigurations") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightConfigurationsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightConfigurationsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FloodlightReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type "FlOODLIGHT".
type FloodlightReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#floodlightReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionFilters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FloodlightReportCompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod FloodlightReportCompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FrequencyCap: Frequency Cap.
type FrequencyCap struct {
	// Duration: Duration of time, in seconds, for this frequency cap. The
	// maximum duration is 90 days in seconds, or 7,776,000.
	Duration int64 `json:"duration,omitempty,string"`

	// Impressions: Number of times an individual user can be served the ad
	// within the specified duration. The maximum allowed is 15.
	Impressions int64 `json:"impressions,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Duration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FrequencyCap) MarshalJSON() ([]byte, error) {
	type noMethod FrequencyCap
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// FsCommand: FsCommand.
type FsCommand struct {
	// Left: Distance from the left of the browser.Applicable when
	// positionOption is DISTANCE_FROM_TOP_LEFT_CORNER.
	Left int64 `json:"left,omitempty"`

	// PositionOption: Position in the browser where the window will open.
	//
	// Possible values:
	//   "CENTERED"
	//   "DISTANCE_FROM_TOP_LEFT_CORNER"
	PositionOption string `json:"positionOption,omitempty"`

	// Top: Distance from the top of the browser. Applicable when
	// positionOption is DISTANCE_FROM_TOP_LEFT_CORNER.
	Top int64 `json:"top,omitempty"`

	// WindowHeight: Height of the window.
	WindowHeight int64 `json:"windowHeight,omitempty"`

	// WindowWidth: Width of the window.
	WindowWidth int64 `json:"windowWidth,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Left") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *FsCommand) MarshalJSON() ([]byte, error) {
	type noMethod FsCommand
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// GeoTargeting: Geographical Targeting.
type GeoTargeting struct {
	// Cities: Cities to be targeted. For each city only dartId is required.
	// The other fields are populated automatically when the ad is inserted
	// or updated. If targeting a city, do not target or exclude the country
	// of the city, and do not target the metro or region of the city.
	Cities []*City `json:"cities,omitempty"`

	// Countries: Countries to be targeted or excluded from targeting,
	// depending on the setting of the excludeCountries field. For each
	// country only dartId is required. The other fields are populated
	// automatically when the ad is inserted or updated. If targeting or
	// excluding a country, do not target regions, cities, metros, or postal
	// codes in the same country.
	Countries []*Country `json:"countries,omitempty"`

	// ExcludeCountries: Whether or not to exclude the countries in the
	// countries field from targeting. If false, the countries field refers
	// to countries which will be targeted by the ad.
	ExcludeCountries bool `json:"excludeCountries,omitempty"`

	// Metros: Metros to be targeted. For each metro only dmaId is required.
	// The other fields are populated automatically when the ad is inserted
	// or updated. If targeting a metro, do not target or exclude the
	// country of the metro.
	Metros []*Metro `json:"metros,omitempty"`

	// PostalCodes: Postal codes to be targeted. For each postal code only
	// id is required. The other fields are populated automatically when the
	// ad is inserted or updated. If targeting a postal code, do not target
	// or exclude the country of the postal code.
	PostalCodes []*PostalCode `json:"postalCodes,omitempty"`

	// Regions: Regions to be targeted. For each region only dartId is
	// required. The other fields are populated automatically when the ad is
	// inserted or updated. If targeting a region, do not target or exclude
	// the country of the region.
	Regions []*Region `json:"regions,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Cities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *GeoTargeting) MarshalJSON() ([]byte, error) {
	type noMethod GeoTargeting
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// KeyValueTargetingExpression: Key Value Targeting Expression.
type KeyValueTargetingExpression struct {
	// Expression: Keyword expression being targeted by the ad.
	Expression string `json:"expression,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Expression") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *KeyValueTargetingExpression) MarshalJSON() ([]byte, error) {
	type noMethod KeyValueTargetingExpression
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// LandingPage: Contains information about where a user's browser is
// taken after the user clicks an ad.
type LandingPage struct {
	// Default: Whether or not this landing page will be assigned to any ads
	// or creatives that do not have a landing page assigned explicitly.
	// Only one default landing page is allowed per campaign.
	Default bool `json:"default,omitempty"`

	// Id: ID of this landing page. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#landingPage".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this landing page. This is a required field. It must be
	// less than 256 characters long, and must be unique among landing pages
	// of the same campaign.
	Name string `json:"name,omitempty"`

	// Url: URL of this landing page. This is a required field.
	Url string `json:"url,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Default") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *LandingPage) MarshalJSON() ([]byte, error) {
	type noMethod LandingPage
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// LandingPagesListResponse: Landing Page List Response
type LandingPagesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#landingPagesListResponse".
	Kind string `json:"kind,omitempty"`

	// LandingPages: Landing page collection
	LandingPages []*LandingPage `json:"landingPages,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *LandingPagesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod LandingPagesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// LastModifiedInfo: Modification timestamp.
type LastModifiedInfo struct {
	// Time: Timestamp of the last change in milliseconds since epoch.
	Time int64 `json:"time,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Time") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *LastModifiedInfo) MarshalJSON() ([]byte, error) {
	type noMethod LastModifiedInfo
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ListTargetingExpression: Remarketing List Targeting Expression.
type ListTargetingExpression struct {
	// Expression: Expression describing which lists are being targeted by
	// the ad.
	Expression string `json:"expression,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Expression") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ListTargetingExpression) MarshalJSON() ([]byte, error) {
	type noMethod ListTargetingExpression
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// LookbackConfiguration: Lookback configuration settings.
type LookbackConfiguration struct {
	// ClickDuration: Lookback window, in days, from the last time a given
	// user clicked on one of your ads. If you enter 0, clicks will not be
	// considered as triggering events for floodlight tracking. If you leave
	// this field blank, the default value for your account will be used.
	ClickDuration int64 `json:"clickDuration,omitempty"`

	// PostImpressionActivitiesDuration: Lookback window, in days, from the
	// last time a given user viewed one of your ads. If you enter 0,
	// impressions will not be considered as triggering events for
	// floodlight tracking. If you leave this field blank, the default value
	// for your account will be used.
	PostImpressionActivitiesDuration int64 `json:"postImpressionActivitiesDuration,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ClickDuration") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *LookbackConfiguration) MarshalJSON() ([]byte, error) {
	type noMethod LookbackConfiguration
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Metric: Represents a metric.
type Metric struct {
	// Kind: The kind of resource this is, in this case dfareporting#metric.
	Kind string `json:"kind,omitempty"`

	// Name: The metric name, e.g. dfa:impressions
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Metric) MarshalJSON() ([]byte, error) {
	type noMethod Metric
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Metro: Contains information about a metro region that can be targeted
// by ads.
type Metro struct {
	// CountryCode: Country code of the country to which this metro region
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this metro region
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this metro region.
	DartId int64 `json:"dartId,omitempty,string"`

	// DmaId: DMA ID of this metro region. This is the ID used for targeting
	// and generating reports, and is equivalent to metro_code.
	DmaId int64 `json:"dmaId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#metro".
	Kind string `json:"kind,omitempty"`

	// MetroCode: Metro code of this metro region. This is equivalent to
	// dma_id.
	MetroCode string `json:"metroCode,omitempty"`

	// Name: Name of this metro region.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Metro) MarshalJSON() ([]byte, error) {
	type noMethod Metro
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// MetrosListResponse: Metro List Response
type MetrosListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#metrosListResponse".
	Kind string `json:"kind,omitempty"`

	// Metros: Metro collection.
	Metros []*Metro `json:"metros,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *MetrosListResponse) MarshalJSON() ([]byte, error) {
	type noMethod MetrosListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// MobileCarrier: Contains information about a mobile carrier that can
// be targeted by ads.
type MobileCarrier struct {
	// CountryCode: Country code of the country to which this mobile carrier
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this mobile carrier
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// Id: ID of this mobile carrier.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileCarrier".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this mobile carrier.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *MobileCarrier) MarshalJSON() ([]byte, error) {
	type noMethod MobileCarrier
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// MobileCarriersListResponse: Mobile Carrier List Response
type MobileCarriersListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#mobileCarriersListResponse".
	Kind string `json:"kind,omitempty"`

	// MobileCarriers: Mobile carrier collection.
	MobileCarriers []*MobileCarrier `json:"mobileCarriers,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *MobileCarriersListResponse) MarshalJSON() ([]byte, error) {
	type noMethod MobileCarriersListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ObjectFilter: Object Filter.
type ObjectFilter struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#objectFilter".
	Kind string `json:"kind,omitempty"`

	// ObjectIds: Applicable when status is ASSIGNED. The user has access to
	// objects with these object IDs.
	ObjectIds googleapi.Int64s `json:"objectIds,omitempty"`

	// Status: Status of the filter. NONE means the user has access to none
	// of the objects. ALL means the user has access to all objects.
	// ASSIGNED means the user has access to the objects with IDs in the
	// objectIds list.
	//
	// Possible values:
	//   "ALL"
	//   "ASSIGNED"
	//   "NONE"
	Status string `json:"status,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ObjectFilter) MarshalJSON() ([]byte, error) {
	type noMethod ObjectFilter
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OffsetPosition: Offset Position.
type OffsetPosition struct {
	// Left: Offset distance from left side of an asset or a window.
	Left int64 `json:"left,omitempty"`

	// Top: Offset distance from top side of an asset or a window.
	Top int64 `json:"top,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Left") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OffsetPosition) MarshalJSON() ([]byte, error) {
	type noMethod OffsetPosition
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OmnitureSettings: Omniture Integration Settings.
type OmnitureSettings struct {
	// OmnitureCostDataEnabled: Whether placement cost data will be sent to
	// Omniture. This property can be enabled only if
	// omnitureIntegrationEnabled is true.
	OmnitureCostDataEnabled bool `json:"omnitureCostDataEnabled,omitempty"`

	// OmnitureIntegrationEnabled: Whether Omniture integration is enabled.
	// This property can be enabled only when the "Advanced Ad Serving"
	// account setting is enabled.
	OmnitureIntegrationEnabled bool `json:"omnitureIntegrationEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "OmnitureCostDataEnabled") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OmnitureSettings) MarshalJSON() ([]byte, error) {
	type noMethod OmnitureSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OperatingSystem: Contains information about an operating system that
// can be targeted by ads.
type OperatingSystem struct {
	// DartId: DART ID of this operating system. This is the ID used for
	// targeting.
	DartId int64 `json:"dartId,omitempty,string"`

	// Desktop: Whether this operating system is for desktop.
	Desktop bool `json:"desktop,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystem".
	Kind string `json:"kind,omitempty"`

	// Mobile: Whether this operating system is for mobile.
	Mobile bool `json:"mobile,omitempty"`

	// Name: Name of this operating system.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DartId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OperatingSystem) MarshalJSON() ([]byte, error) {
	type noMethod OperatingSystem
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OperatingSystemVersion: Contains information about a particular
// version of an operating system that can be targeted by ads.
type OperatingSystemVersion struct {
	// Id: ID of this operating system version.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemVersion".
	Kind string `json:"kind,omitempty"`

	// MajorVersion: Major version (leftmost number) of this operating
	// system version.
	MajorVersion string `json:"majorVersion,omitempty"`

	// MinorVersion: Minor version (number after the first dot) of this
	// operating system version.
	MinorVersion string `json:"minorVersion,omitempty"`

	// Name: Name of this operating system version.
	Name string `json:"name,omitempty"`

	// OperatingSystem: Operating system of this operating system version.
	OperatingSystem *OperatingSystem `json:"operatingSystem,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OperatingSystemVersion) MarshalJSON() ([]byte, error) {
	type noMethod OperatingSystemVersion
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OperatingSystemVersionsListResponse: Operating System Version List
// Response
type OperatingSystemVersionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemVersionsListResponse".
	Kind string `json:"kind,omitempty"`

	// OperatingSystemVersions: Operating system version collection.
	OperatingSystemVersions []*OperatingSystemVersion `json:"operatingSystemVersions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OperatingSystemVersionsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod OperatingSystemVersionsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OperatingSystemsListResponse: Operating System List Response
type OperatingSystemsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#operatingSystemsListResponse".
	Kind string `json:"kind,omitempty"`

	// OperatingSystems: Operating system collection.
	OperatingSystems []*OperatingSystem `json:"operatingSystems,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OperatingSystemsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod OperatingSystemsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// OptimizationActivity: Creative optimization activity.
type OptimizationActivity struct {
	// FloodlightActivityId: Floodlight activity ID of this optimization
	// activity. This is a required field.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightActivityIdDimensionValue: Dimension value for the ID of the
	// floodlight activity. This is a read-only, auto-generated field.
	FloodlightActivityIdDimensionValue *DimensionValue `json:"floodlightActivityIdDimensionValue,omitempty"`

	// Weight: Weight associated with this optimization. Must be greater
	// than 1. The weight assigned will be understood in proportion to the
	// weights assigned to the other optimization activities.
	Weight int64 `json:"weight,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "FloodlightActivityId") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *OptimizationActivity) MarshalJSON() ([]byte, error) {
	type noMethod OptimizationActivity
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PathToConversionReportCompatibleFields: Represents fields that are
// compatible to be selected for a report of type "PATH_TO_CONVERSION".
type PathToConversionReportCompatibleFields struct {
	// ConversionDimensions: Conversion dimensions which are compatible to
	// be selected in the "conversionDimensions" section of the report.
	ConversionDimensions []*Dimension `json:"conversionDimensions,omitempty"`

	// CustomFloodlightVariables: Custom floodlight variables which are
	// compatible to be selected in the "customFloodlightVariables" section
	// of the report.
	CustomFloodlightVariables []*Dimension `json:"customFloodlightVariables,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#pathToConversionReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PerInteractionDimensions: Per-interaction dimensions which are
	// compatible to be selected in the "perInteractionDimensions" section
	// of the report.
	PerInteractionDimensions []*Dimension `json:"perInteractionDimensions,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ConversionDimensions") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PathToConversionReportCompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod PathToConversionReportCompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Placement: Contains properties of a placement.
type Placement struct {
	// AccountId: Account ID of this placement. This field can be left
	// blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this placement. This field can be left
	// blank.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this placement is archived.
	Archived bool `json:"archived,omitempty"`

	// CampaignId: Campaign ID of this placement. This field is a required
	// field on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// Comment: Comments for this placement.
	Comment string `json:"comment,omitempty"`

	// Compatibility: Placement compatibility. WEB and WEB_INTERSTITIAL
	// refer to rendering either on desktop or on mobile devices for regular
	// or interstitial ads, respectively. APP and APP_INTERSTITIAL are for
	// rendering in mobile apps. IN_STREAM_VIDEO refers to rendering in
	// in-stream video ads developed with the VAST standard. This field is
	// required on insertion.
	//
	// Possible values:
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	//   "WEB"
	//   "WEB_INTERSTITIAL"
	Compatibility string `json:"compatibility,omitempty"`

	// ContentCategoryId: ID of the content category assigned to this
	// placement.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// CreateInfo: Information about the creation of this placement. This is
	// a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// DirectorySiteId: Directory site ID of this placement. On insert, you
	// must set either this field or the siteId field to specify the site
	// associated with this placement. This is a required field that is
	// read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// ExternalId: External ID for this placement.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this placement. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this placement. This
	// is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyName: Key name of this placement. This is a read-only,
	// auto-generated field.
	KeyName string `json:"keyName,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placement".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this placement. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// LookbackConfiguration: Lookback window settings for this placement.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// Name: Name of this placement.This is a required field and must be
	// less than 256 characters long.
	Name string `json:"name,omitempty"`

	// PaymentApproved: Whether payment was approved for this placement.
	// This is a read-only field relevant only to publisher-paid placements.
	PaymentApproved bool `json:"paymentApproved,omitempty"`

	// PaymentSource: Payment source for this placement. This is a required
	// field that is read-only after insertion.
	//
	// Possible values:
	//   "PLACEMENT_AGENCY_PAID"
	//   "PLACEMENT_PUBLISHER_PAID"
	PaymentSource string `json:"paymentSource,omitempty"`

	// PlacementGroupId: ID of this placement's group, if applicable.
	PlacementGroupId int64 `json:"placementGroupId,omitempty,string"`

	// PlacementGroupIdDimensionValue: Dimension value for the ID of the
	// placement group. This is a read-only, auto-generated field.
	PlacementGroupIdDimensionValue *DimensionValue `json:"placementGroupIdDimensionValue,omitempty"`

	// PlacementStrategyId: ID of the placement strategy assigned to this
	// placement.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// PricingSchedule: Pricing schedule of this placement. This field is
	// required on insertion, specifically subfields startDate, endDate and
	// pricingType.
	PricingSchedule *PricingSchedule `json:"pricingSchedule,omitempty"`

	// Primary: Whether this placement is the primary placement of a
	// roadblock (placement group). You cannot change this field from true
	// to false. Setting this field to true will automatically set the
	// primary field on the original primary placement of the roadblock to
	// false, and it will automatically set the roadblock's
	// primaryPlacementId field to the ID of this placement.
	Primary bool `json:"primary,omitempty"`

	// PublisherUpdateInfo: Information about the last publisher update.
	// This is a read-only field.
	PublisherUpdateInfo *LastModifiedInfo `json:"publisherUpdateInfo,omitempty"`

	// SiteId: Site ID associated with this placement. On insert, you must
	// set either this field or the directorySiteId field to specify the
	// site associated with this placement. This is a required field that is
	// read-only after insertion.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// Size: Size associated with this placement. When inserting or updating
	// a placement, only the size ID field is used. This field is required
	// on insertion.
	Size *Size `json:"size,omitempty"`

	// SslRequired: Whether creatives assigned to this placement must be
	// SSL-compliant.
	SslRequired bool `json:"sslRequired,omitempty"`

	// Status: Third-party placement status.
	//
	// Possible values:
	//   "ACKNOWLEDGE_ACCEPTANCE"
	//   "ACKNOWLEDGE_REJECTION"
	//   "DRAFT"
	//   "PAYMENT_ACCEPTED"
	//   "PAYMENT_REJECTED"
	//   "PENDING_REVIEW"
	Status string `json:"status,omitempty"`

	// SubaccountId: Subaccount ID of this placement. This field can be left
	// blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TagFormats: Tag formats to generate for this placement. This field is
	// required on insertion.
	// Acceptable values are:
	// - "PLACEMENT_TAG_STANDARD"
	// - "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
	// - "PLACEMENT_TAG_IFRAME_ILAYER"
	// - "PLACEMENT_TAG_INTERNAL_REDIRECT"
	// - "PLACEMENT_TAG_JAVASCRIPT"
	// - "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
	// - "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
	// - "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
	// - "PLACEMENT_TAG_CLICK_COMMANDS"
	// - "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
	// - "PLACEMENT_TAG_TRACKING"
	// - "PLACEMENT_TAG_TRACKING_IFRAME"
	// - "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	//
	// Possible values:
	//   "PLACEMENT_TAG_CLICK_COMMANDS"
	//   "PLACEMENT_TAG_IFRAME_ILAYER"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
	//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_JAVASCRIPT"
	//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_STANDARD"
	//   "PLACEMENT_TAG_TRACKING"
	//   "PLACEMENT_TAG_TRACKING_IFRAME"
	//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	TagFormats []string `json:"tagFormats,omitempty"`

	// TagSetting: Tag settings for this placement.
	TagSetting *TagSetting `json:"tagSetting,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Placement) MarshalJSON() ([]byte, error) {
	type noMethod Placement
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementAssignment: Placement Assignment.
type PlacementAssignment struct {
	// Active: Whether this placement assignment is active. When true, the
	// placement will be included in the ad's rotation.
	Active bool `json:"active,omitempty"`

	// PlacementId: ID of the placement to be assigned. This is a required
	// field.
	PlacementId int64 `json:"placementId,omitempty,string"`

	// PlacementIdDimensionValue: Dimension value for the ID of the
	// placement. This is a read-only, auto-generated field.
	PlacementIdDimensionValue *DimensionValue `json:"placementIdDimensionValue,omitempty"`

	// SslRequired: Whether the placement to be assigned requires SSL. This
	// is a read-only field that is auto-generated when the ad is inserted
	// or updated.
	SslRequired bool `json:"sslRequired,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Active") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementAssignment) MarshalJSON() ([]byte, error) {
	type noMethod PlacementAssignment
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementGroup: Contains properties of a package or roadblock.
type PlacementGroup struct {
	// AccountId: Account ID of this placement group. This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this placement group. This is a
	// required field on insertion.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser. This is a read-only, auto-generated field.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Archived: Whether this placement group is archived.
	Archived bool `json:"archived,omitempty"`

	// CampaignId: Campaign ID of this placement group. This field is
	// required on insertion.
	CampaignId int64 `json:"campaignId,omitempty,string"`

	// CampaignIdDimensionValue: Dimension value for the ID of the campaign.
	// This is a read-only, auto-generated field.
	CampaignIdDimensionValue *DimensionValue `json:"campaignIdDimensionValue,omitempty"`

	// ChildPlacementIds: IDs of placements which are assigned to this
	// placement group. This is a read-only, auto-generated field.
	ChildPlacementIds googleapi.Int64s `json:"childPlacementIds,omitempty"`

	// Comment: Comments for this placement group.
	Comment string `json:"comment,omitempty"`

	// ContentCategoryId: ID of the content category assigned to this
	// placement group.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// CreateInfo: Information about the creation of this placement group.
	// This is a read-only field.
	CreateInfo *LastModifiedInfo `json:"createInfo,omitempty"`

	// DirectorySiteId: Directory site ID associated with this placement
	// group. On insert, you must set either this field or the site_id field
	// to specify the site associated with this placement group. This is a
	// required field that is read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// ExternalId: External ID for this placement.
	ExternalId string `json:"externalId,omitempty"`

	// Id: ID of this placement group. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this placement group.
	// This is a read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementGroup".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this placement group. This is a read-only field.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this placement group. This is a required field and must
	// be less than 256 characters long.
	Name string `json:"name,omitempty"`

	// PlacementGroupType: Type of this placement group. A package is a
	// simple group of placements that acts as a single pricing point for a
	// group of tags. A roadblock is a group of placements that not only
	// acts as a single pricing point, but also assumes that all the tags in
	// it will be served at the same time. A roadblock requires one of its
	// assigned placements to be marked as primary for reporting. This field
	// is required on insertion.
	//
	// Possible values:
	//   "PLACEMENT_PACKAGE"
	//   "PLACEMENT_ROADBLOCK"
	PlacementGroupType string `json:"placementGroupType,omitempty"`

	// PlacementStrategyId: ID of the placement strategy assigned to this
	// placement group.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// PricingSchedule: Pricing schedule of this placement group. This field
	// is required on insertion.
	PricingSchedule *PricingSchedule `json:"pricingSchedule,omitempty"`

	// PrimaryPlacementId: ID of the primary placement, used to calculate
	// the media cost of a roadblock (placement group). Modifying this field
	// will automatically modify the primary field on all affected roadblock
	// child placements.
	PrimaryPlacementId int64 `json:"primaryPlacementId,omitempty,string"`

	// PrimaryPlacementIdDimensionValue: Dimension value for the ID of the
	// primary placement. This is a read-only, auto-generated field.
	PrimaryPlacementIdDimensionValue *DimensionValue `json:"primaryPlacementIdDimensionValue,omitempty"`

	// ProgrammaticSetting: Settings for a programmatic placement.
	ProgrammaticSetting *ProgrammaticSetting `json:"programmaticSetting,omitempty"`

	// SiteId: Site ID associated with this placement group. On insert, you
	// must set either this field or the directorySiteId field to specify
	// the site associated with this placement group. This is a required
	// field that is read-only after insertion.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SiteIdDimensionValue: Dimension value for the ID of the site. This is
	// a read-only, auto-generated field.
	SiteIdDimensionValue *DimensionValue `json:"siteIdDimensionValue,omitempty"`

	// SubaccountId: Subaccount ID of this placement group. This is a
	// read-only field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementGroup) MarshalJSON() ([]byte, error) {
	type noMethod PlacementGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementGroupsListResponse: Placement Group List Response
type PlacementGroupsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PlacementGroups: Placement group collection.
	PlacementGroups []*PlacementGroup `json:"placementGroups,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod PlacementGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementStrategiesListResponse: Placement Strategy List Response
type PlacementStrategiesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementStrategiesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// PlacementStrategies: Placement strategy collection.
	PlacementStrategies []*PlacementStrategy `json:"placementStrategies,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementStrategiesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod PlacementStrategiesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementStrategy: Contains properties of a placement strategy.
type PlacementStrategy struct {
	// AccountId: Account ID of this placement strategy.This is a read-only
	// field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Id: ID of this placement strategy. This is a read-only,
	// auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementStrategy".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this placement strategy. This is a required field. It
	// must be less than 256 characters long and unique among placement
	// strategies of the same account.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementStrategy) MarshalJSON() ([]byte, error) {
	type noMethod PlacementStrategy
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementTag: Placement Tag
type PlacementTag struct {
	// PlacementId: Placement ID
	PlacementId int64 `json:"placementId,omitempty,string"`

	// TagDatas: Tags generated for this placement.
	TagDatas []*TagData `json:"tagDatas,omitempty"`

	// ForceSendFields is a list of field names (e.g. "PlacementId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementTag) MarshalJSON() ([]byte, error) {
	type noMethod PlacementTag
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementsGenerateTagsResponse: Placement GenerateTags Response
type PlacementsGenerateTagsResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementsGenerateTagsResponse".
	Kind string `json:"kind,omitempty"`

	// PlacementTags: Set of generated tags for the specified placements.
	PlacementTags []*PlacementTag `json:"placementTags,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementsGenerateTagsResponse) MarshalJSON() ([]byte, error) {
	type noMethod PlacementsGenerateTagsResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlacementsListResponse: Placement List Response
type PlacementsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#placementsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Placements: Placement collection.
	Placements []*Placement `json:"placements,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlacementsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod PlacementsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlatformType: Contains information about a platform type that can be
// targeted by ads.
type PlatformType struct {
	// Id: ID of this platform type.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#platformType".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this platform type.
	Name string `json:"name,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlatformType) MarshalJSON() ([]byte, error) {
	type noMethod PlatformType
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PlatformTypesListResponse: Platform Type List Response
type PlatformTypesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#platformTypesListResponse".
	Kind string `json:"kind,omitempty"`

	// PlatformTypes: Platform type collection.
	PlatformTypes []*PlatformType `json:"platformTypes,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PlatformTypesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod PlatformTypesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PopupWindowProperties: Popup Window Properties.
type PopupWindowProperties struct {
	// Dimension: Popup dimension for a creative. This is a read-only field.
	// Applicable to the following creative types: all RICH_MEDIA and all
	// VPAID
	Dimension *Size `json:"dimension,omitempty"`

	// Offset: Upper-left corner coordinates of the popup window. Applicable
	// if positionType is COORDINATES.
	Offset *OffsetPosition `json:"offset,omitempty"`

	// PositionType: Popup window position either centered or at specific
	// coordinate.
	//
	// Possible values:
	//   "CENTER"
	//   "COORDINATES"
	PositionType string `json:"positionType,omitempty"`

	// ShowAddressBar: Whether to display the browser address bar.
	ShowAddressBar bool `json:"showAddressBar,omitempty"`

	// ShowMenuBar: Whether to display the browser menu bar.
	ShowMenuBar bool `json:"showMenuBar,omitempty"`

	// ShowScrollBar: Whether to display the browser scroll bar.
	ShowScrollBar bool `json:"showScrollBar,omitempty"`

	// ShowStatusBar: Whether to display the browser status bar.
	ShowStatusBar bool `json:"showStatusBar,omitempty"`

	// ShowToolBar: Whether to display the browser tool bar.
	ShowToolBar bool `json:"showToolBar,omitempty"`

	// Title: Title of popup window.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Dimension") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PopupWindowProperties) MarshalJSON() ([]byte, error) {
	type noMethod PopupWindowProperties
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PostalCode: Contains information about a postal code that can be
// targeted by ads.
type PostalCode struct {
	// CountryCode: Country code of the country to which this postal code
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this postal code
	// belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// Id: ID of this postal code.
	Id string `json:"id,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#postalCode".
	Kind string `json:"kind,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PostalCode) MarshalJSON() ([]byte, error) {
	type noMethod PostalCode
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PostalCodesListResponse: Postal Code List Response
type PostalCodesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#postalCodesListResponse".
	Kind string `json:"kind,omitempty"`

	// PostalCodes: Postal code collection.
	PostalCodes []*PostalCode `json:"postalCodes,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PostalCodesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod PostalCodesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PricingSchedule: Pricing Schedule
type PricingSchedule struct {
	// CapCostOption: Placement cap cost option.
	//
	// Possible values:
	//   "CAP_COST_CUMULATIVE"
	//   "CAP_COST_MONTHLY"
	//   "CAP_COST_NONE"
	CapCostOption string `json:"capCostOption,omitempty"`

	// DisregardOverdelivery: Whether cap costs are ignored by ad serving.
	DisregardOverdelivery bool `json:"disregardOverdelivery,omitempty"`

	// EndDate: Placement end date. This date must be later than, or the
	// same day as, the placement start date, but not later than the
	// campaign end date. If, for example, you set 6/25/2015 as both the
	// start and end dates, the effective placement date is just that day
	// only, 6/25/2015. The hours, minutes, and seconds of the end date
	// should not be set, as doing so will result in an error. This field is
	// required on insertion.
	EndDate string `json:"endDate,omitempty"`

	// Flighted: Whether this placement is flighted. If true, pricing
	// periods will be computed automatically.
	Flighted bool `json:"flighted,omitempty"`

	// FloodlightActivityId: Floodlight activity ID associated with this
	// placement. This field should be set when placement pricing type is
	// set to PRICING_TYPE_CPA.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// PricingPeriods: Pricing periods for this placement.
	PricingPeriods []*PricingSchedulePricingPeriod `json:"pricingPeriods,omitempty"`

	// PricingType: Placement pricing type. This field is required on
	// insertion.
	//
	// Possible values:
	//   "PRICING_TYPE_CPA"
	//   "PRICING_TYPE_CPC"
	//   "PRICING_TYPE_CPM"
	//   "PRICING_TYPE_FLAT_RATE_CLICKS"
	//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	PricingType string `json:"pricingType,omitempty"`

	// StartDate: Placement start date. This date must be later than, or the
	// same day as, the campaign start date. The hours, minutes, and seconds
	// of the start date should not be set, as doing so will result in an
	// error. This field is required on insertion.
	StartDate string `json:"startDate,omitempty"`

	// TestingStartDate: Testing start date of this placement. The hours,
	// minutes, and seconds of the start date should not be set, as doing so
	// will result in an error.
	TestingStartDate string `json:"testingStartDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CapCostOption") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PricingSchedule) MarshalJSON() ([]byte, error) {
	type noMethod PricingSchedule
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// PricingSchedulePricingPeriod: Pricing Period
type PricingSchedulePricingPeriod struct {
	// EndDate: Pricing period end date. This date must be later than, or
	// the same day as, the pricing period start date, but not later than
	// the placement end date. The period end date can be the same date as
	// the period start date. If, for example, you set 6/25/2015 as both the
	// start and end dates, the effective pricing period date is just that
	// day only, 6/25/2015. The hours, minutes, and seconds of the end date
	// should not be set, as doing so will result in an error.
	EndDate string `json:"endDate,omitempty"`

	// PricingComment: Comments for this pricing period.
	PricingComment string `json:"pricingComment,omitempty"`

	// RateOrCostNanos: Rate or cost of this pricing period.
	RateOrCostNanos int64 `json:"rateOrCostNanos,omitempty,string"`

	// StartDate: Pricing period start date. This date must be later than,
	// or the same day as, the placement start date. The hours, minutes, and
	// seconds of the start date should not be set, as doing so will result
	// in an error.
	StartDate string `json:"startDate,omitempty"`

	// Units: Units of this pricing period.
	Units int64 `json:"units,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "EndDate") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *PricingSchedulePricingPeriod) MarshalJSON() ([]byte, error) {
	type noMethod PricingSchedulePricingPeriod
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ProgrammaticSetting: Programmatic Setting
type ProgrammaticSetting struct {
	// AdxDealIds: Adx deal IDs assigned to the placement.
	AdxDealIds googleapi.Int64s `json:"adxDealIds,omitempty"`

	// InsertionOrderId: Insertion order ID.
	InsertionOrderId string `json:"insertionOrderId,omitempty"`

	// InsertionOrderIdStatus: Whether insertion order ID has been placed in
	// DFP. This is a read-only field.
	InsertionOrderIdStatus bool `json:"insertionOrderIdStatus,omitempty"`

	// MediaCostNanos: Media cost for the programmatic placement.
	MediaCostNanos int64 `json:"mediaCostNanos,omitempty,string"`

	// Programmatic: Whether programmatic is enabled.
	Programmatic bool `json:"programmatic,omitempty"`

	// TraffickerEmails: Trafficker emails assigned to the placement.
	TraffickerEmails []string `json:"traffickerEmails,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdxDealIds") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ProgrammaticSetting) MarshalJSON() ([]byte, error) {
	type noMethod ProgrammaticSetting
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReachReportCompatibleFields: Represents fields that are compatible to
// be selected for a report of type "REACH".
type ReachReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#reachReportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PivotedActivityMetrics: Metrics which are compatible to be selected
	// as activity metrics to pivot on in the "activities" section of the
	// report.
	PivotedActivityMetrics []*Metric `json:"pivotedActivityMetrics,omitempty"`

	// ReachByFrequencyMetrics: Metrics which are compatible to be selected
	// in the "reachByFrequencyMetricNames" section of the report.
	ReachByFrequencyMetrics []*Metric `json:"reachByFrequencyMetrics,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionFilters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReachReportCompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod ReachReportCompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Recipient: Represents a recipient.
type Recipient struct {
	// DeliveryType: The delivery type for the recipient.
	//
	// Possible values:
	//   "ATTACHMENT"
	//   "LINK"
	DeliveryType string `json:"deliveryType,omitempty"`

	// Email: The email address of the recipient.
	Email string `json:"email,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#recipient.
	Kind string `json:"kind,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DeliveryType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Recipient) MarshalJSON() ([]byte, error) {
	type noMethod Recipient
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Region: Contains information about a region that can be targeted by
// ads.
type Region struct {
	// CountryCode: Country code of the country to which this region
	// belongs.
	CountryCode string `json:"countryCode,omitempty"`

	// CountryDartId: DART ID of the country to which this region belongs.
	CountryDartId int64 `json:"countryDartId,omitempty,string"`

	// DartId: DART ID of this region.
	DartId int64 `json:"dartId,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#region".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this region.
	Name string `json:"name,omitempty"`

	// RegionCode: Region code.
	RegionCode string `json:"regionCode,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CountryCode") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Region) MarshalJSON() ([]byte, error) {
	type noMethod Region
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// RegionsListResponse: Region List Response
type RegionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#regionsListResponse".
	Kind string `json:"kind,omitempty"`

	// Regions: Region collection.
	Regions []*Region `json:"regions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *RegionsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod RegionsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Report: Represents a Report resource.
type Report struct {
	// AccountId: The account ID to which this report belongs.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Criteria: The report criteria for a report of type "STANDARD".
	Criteria *ReportCriteria `json:"criteria,omitempty"`

	// CrossDimensionReachCriteria: The report criteria for a report of type
	// "CROSS_DIMENSION_REACH".
	CrossDimensionReachCriteria *ReportCrossDimensionReachCriteria `json:"crossDimensionReachCriteria,omitempty"`

	// Delivery: The report's email delivery settings.
	Delivery *ReportDelivery `json:"delivery,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// FileName: The filename used when generating report files for this
	// report.
	FileName string `json:"fileName,omitempty"`

	// FloodlightCriteria: The report criteria for a report of type
	// "FLOODLIGHT".
	FloodlightCriteria *ReportFloodlightCriteria `json:"floodlightCriteria,omitempty"`

	// Format: The output format of the report. If not specified, default
	// format is "CSV". Note that the actual format in the completed report
	// file might differ if for instance the report's size exceeds the
	// format's capabilities. "CSV" will then be the fallback format.
	//
	// Possible values:
	//   "CSV"
	//   "EXCEL"
	Format string `json:"format,omitempty"`

	// Id: The unique ID identifying this report resource.
	Id int64 `json:"id,omitempty,string"`

	// Kind: The kind of resource this is, in this case dfareporting#report.
	Kind string `json:"kind,omitempty"`

	// LastModifiedTime: The timestamp (in milliseconds since epoch) of when
	// this report was last modified.
	LastModifiedTime uint64 `json:"lastModifiedTime,omitempty,string"`

	// Name: The name of the report.
	Name string `json:"name,omitempty"`

	// OwnerProfileId: The user profile id of the owner of this report.
	OwnerProfileId int64 `json:"ownerProfileId,omitempty,string"`

	// PathToConversionCriteria: The report criteria for a report of type
	// "PATH_TO_CONVERSION".
	PathToConversionCriteria *ReportPathToConversionCriteria `json:"pathToConversionCriteria,omitempty"`

	// ReachCriteria: The report criteria for a report of type "REACH".
	ReachCriteria *ReportReachCriteria `json:"reachCriteria,omitempty"`

	// Schedule: The report's schedule. Can only be set if the report's
	// 'dateRange' is a relative date range and the relative date range is
	// not "TODAY".
	Schedule *ReportSchedule `json:"schedule,omitempty"`

	// SubAccountId: The subaccount ID to which this report belongs if
	// applicable.
	SubAccountId int64 `json:"subAccountId,omitempty,string"`

	// Type: The type of the report.
	//
	// Possible values:
	//   "CROSS_DIMENSION_REACH"
	//   "FLOODLIGHT"
	//   "PATH_TO_CONVERSION"
	//   "REACH"
	//   "STANDARD"
	Type string `json:"type,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Report) MarshalJSON() ([]byte, error) {
	type noMethod Report
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportCriteria: The report criteria for a report of type "STANDARD".
type ReportCriteria struct {
	// Activities: Activity group.
	Activities *Activities `json:"activities,omitempty"`

	// CustomRichMediaEvents: Custom Rich Media Events group.
	CustomRichMediaEvents *CustomRichMediaEvents `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range for which this report should be run.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered.
	// Filters for different dimensions are ANDed, filters for the same
	// dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of standard dimensions the report should
	// include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Activities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportCriteria) MarshalJSON() ([]byte, error) {
	type noMethod ReportCriteria
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportCrossDimensionReachCriteria: The report criteria for a report
// of type "CROSS_DIMENSION_REACH".
type ReportCrossDimensionReachCriteria struct {
	// Breakdown: The list of dimensions the report should include.
	Breakdown []*SortedDimension `json:"breakdown,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// Dimension: The dimension option.
	//
	// Possible values:
	//   "ADVERTISER"
	//   "CAMPAIGN"
	//   "SITE_BY_ADVERTISER"
	//   "SITE_BY_CAMPAIGN"
	Dimension string `json:"dimension,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// OverlapMetricNames: The list of names of overlap metrics the report
	// should include.
	OverlapMetricNames []string `json:"overlapMetricNames,omitempty"`

	// Pivoted: Whether the report is pivoted or not. Defaults to true.
	Pivoted bool `json:"pivoted,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Breakdown") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportCrossDimensionReachCriteria) MarshalJSON() ([]byte, error) {
	type noMethod ReportCrossDimensionReachCriteria
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportDelivery: The report's email delivery settings.
type ReportDelivery struct {
	// EmailOwner: Whether the report should be emailed to the report owner.
	EmailOwner bool `json:"emailOwner,omitempty"`

	// EmailOwnerDeliveryType: The type of delivery for the owner to
	// receive, if enabled.
	//
	// Possible values:
	//   "ATTACHMENT"
	//   "LINK"
	EmailOwnerDeliveryType string `json:"emailOwnerDeliveryType,omitempty"`

	// Message: The message to be sent with each email.
	Message string `json:"message,omitempty"`

	// Recipients: The list of recipients to which to email the report.
	Recipients []*Recipient `json:"recipients,omitempty"`

	// ForceSendFields is a list of field names (e.g. "EmailOwner") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportDelivery) MarshalJSON() ([]byte, error) {
	type noMethod ReportDelivery
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportFloodlightCriteria: The report criteria for a report of type
// "FLOODLIGHT".
type ReportFloodlightCriteria struct {
	// CustomRichMediaEvents: The list of custom rich media events to
	// include.
	CustomRichMediaEvents []*DimensionValue `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered.
	// Filters for different dimensions are ANDed, filters for the same
	// dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// ReportProperties: The properties of the report.
	ReportProperties *ReportFloodlightCriteriaReportProperties `json:"reportProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "CustomRichMediaEvents") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportFloodlightCriteria) MarshalJSON() ([]byte, error) {
	type noMethod ReportFloodlightCriteria
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportFloodlightCriteriaReportProperties: The properties of the
// report.
type ReportFloodlightCriteriaReportProperties struct {
	// IncludeAttributedIPConversions: Include conversions that have no
	// cookie, but do have an exposure path.
	IncludeAttributedIPConversions bool `json:"includeAttributedIPConversions,omitempty"`

	// IncludeUnattributedCookieConversions: Include conversions of users
	// with a DoubleClick cookie but without an exposure. That means the
	// user did not click or see an ad from the advertiser within the
	// Floodlight group, or that the interaction happened outside the
	// lookback window.
	IncludeUnattributedCookieConversions bool `json:"includeUnattributedCookieConversions,omitempty"`

	// IncludeUnattributedIPConversions: Include conversions that have no
	// associated cookies and no exposures. It’s therefore impossible to
	// know how the user was exposed to your ads during the lookback window
	// prior to a conversion.
	IncludeUnattributedIPConversions bool `json:"includeUnattributedIPConversions,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "IncludeAttributedIPConversions") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportFloodlightCriteriaReportProperties) MarshalJSON() ([]byte, error) {
	type noMethod ReportFloodlightCriteriaReportProperties
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportPathToConversionCriteria: The report criteria for a report of
// type "PATH_TO_CONVERSION".
type ReportPathToConversionCriteria struct {
	// ActivityFilters: The list of 'dfa:activity' values to filter on.
	ActivityFilters []*DimensionValue `json:"activityFilters,omitempty"`

	// ConversionDimensions: The list of conversion dimensions the report
	// should include.
	ConversionDimensions []*SortedDimension `json:"conversionDimensions,omitempty"`

	// CustomFloodlightVariables: The list of custom floodlight variables
	// the report should include.
	CustomFloodlightVariables []*SortedDimension `json:"customFloodlightVariables,omitempty"`

	// CustomRichMediaEvents: The list of custom rich media events to
	// include.
	CustomRichMediaEvents []*DimensionValue `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// FloodlightConfigId: The floodlight ID for which to show data in this
	// report. All advertisers associated with that ID will automatically be
	// added. The dimension of the value needs to be
	// 'dfa:floodlightConfigId'.
	FloodlightConfigId *DimensionValue `json:"floodlightConfigId,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// PerInteractionDimensions: The list of per interaction dimensions the
	// report should include.
	PerInteractionDimensions []*SortedDimension `json:"perInteractionDimensions,omitempty"`

	// ReportProperties: The properties of the report.
	ReportProperties *ReportPathToConversionCriteriaReportProperties `json:"reportProperties,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActivityFilters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportPathToConversionCriteria) MarshalJSON() ([]byte, error) {
	type noMethod ReportPathToConversionCriteria
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportPathToConversionCriteriaReportProperties: The properties of the
// report.
type ReportPathToConversionCriteriaReportProperties struct {
	// ClicksLookbackWindow: DFA checks to see if a click interaction
	// occurred within the specified period of time before a conversion. By
	// default the value is pulled from Floodlight or you can manually enter
	// a custom value. Valid values: 1-90.
	ClicksLookbackWindow int64 `json:"clicksLookbackWindow,omitempty"`

	// ImpressionsLookbackWindow: DFA checks to see if an impression
	// interaction occurred within the specified period of time before a
	// conversion. By default the value is pulled from Floodlight or you can
	// manually enter a custom value. Valid values: 1-90.
	ImpressionsLookbackWindow int64 `json:"impressionsLookbackWindow,omitempty"`

	// IncludeAttributedIPConversions: Deprecated: has no effect.
	IncludeAttributedIPConversions bool `json:"includeAttributedIPConversions,omitempty"`

	// IncludeUnattributedCookieConversions: Include conversions of users
	// with a DoubleClick cookie but without an exposure. That means the
	// user did not click or see an ad from the advertiser within the
	// Floodlight group, or that the interaction happened outside the
	// lookback window.
	IncludeUnattributedCookieConversions bool `json:"includeUnattributedCookieConversions,omitempty"`

	// IncludeUnattributedIPConversions: Include conversions that have no
	// associated cookies and no exposures. It’s therefore impossible to
	// know how the user was exposed to your ads during the lookback window
	// prior to a conversion.
	IncludeUnattributedIPConversions bool `json:"includeUnattributedIPConversions,omitempty"`

	// MaximumClickInteractions: The maximum number of click interactions to
	// include in the report. Advertisers currently paying for E2C reports
	// get up to 200 (100 clicks, 100 impressions). If another advertiser in
	// your network is paying for E2C, you can have up to 5 total exposures
	// per report.
	MaximumClickInteractions int64 `json:"maximumClickInteractions,omitempty"`

	// MaximumImpressionInteractions: The maximum number of click
	// interactions to include in the report. Advertisers currently paying
	// for E2C reports get up to 200 (100 clicks, 100 impressions). If
	// another advertiser in your network is paying for E2C, you can have up
	// to 5 total exposures per report.
	MaximumImpressionInteractions int64 `json:"maximumImpressionInteractions,omitempty"`

	// MaximumInteractionGap: The maximum amount of time that can take place
	// between interactions (clicks or impressions) by the same user. Valid
	// values: 1-90.
	MaximumInteractionGap int64 `json:"maximumInteractionGap,omitempty"`

	// PivotOnInteractionPath: Enable pivoting on interaction path.
	PivotOnInteractionPath bool `json:"pivotOnInteractionPath,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ClicksLookbackWindow") to unconditionally include in API requests.
	// By default, fields with empty values are omitted from API requests.
	// However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportPathToConversionCriteriaReportProperties) MarshalJSON() ([]byte, error) {
	type noMethod ReportPathToConversionCriteriaReportProperties
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportReachCriteria: The report criteria for a report of type
// "REACH".
type ReportReachCriteria struct {
	// Activities: Activity group.
	Activities *Activities `json:"activities,omitempty"`

	// CustomRichMediaEvents: Custom Rich Media Events group.
	CustomRichMediaEvents *CustomRichMediaEvents `json:"customRichMediaEvents,omitempty"`

	// DateRange: The date range this report should be run for.
	DateRange *DateRange `json:"dateRange,omitempty"`

	// DimensionFilters: The list of filters on which dimensions are
	// filtered.
	// Filters for different dimensions are ANDed, filters for the same
	// dimension are grouped together and ORed.
	DimensionFilters []*DimensionValue `json:"dimensionFilters,omitempty"`

	// Dimensions: The list of dimensions the report should include.
	Dimensions []*SortedDimension `json:"dimensions,omitempty"`

	// EnableAllDimensionCombinations: Whether to enable all reach dimension
	// combinations in the report. Defaults to false. If enabled, the date
	// range of the report should be within the last three months.
	EnableAllDimensionCombinations bool `json:"enableAllDimensionCombinations,omitempty"`

	// MetricNames: The list of names of metrics the report should include.
	MetricNames []string `json:"metricNames,omitempty"`

	// ReachByFrequencyMetricNames: The list of names of  Reach By Frequency
	// metrics the report should include.
	ReachByFrequencyMetricNames []string `json:"reachByFrequencyMetricNames,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Activities") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportReachCriteria) MarshalJSON() ([]byte, error) {
	type noMethod ReportReachCriteria
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportSchedule: The report's schedule. Can only be set if the
// report's 'dateRange' is a relative date range and the relative date
// range is not "TODAY".
type ReportSchedule struct {
	// Active: Whether the schedule is active or not. Must be set to either
	// true or false.
	Active bool `json:"active,omitempty"`

	// Every: Defines every how many days, weeks or months the report should
	// be run. Needs to be set when "repeats" is either "DAILY", "WEEKLY" or
	// "MONTHLY".
	Every int64 `json:"every,omitempty"`

	// ExpirationDate: The expiration date when the scheduled report stops
	// running.
	ExpirationDate string `json:"expirationDate,omitempty"`

	// Repeats: The interval for which the report is repeated. Note:
	// - "DAILY" also requires field "every" to be set.
	// - "WEEKLY" also requires fields "every" and "repeatsOnWeekDays" to be
	// set.
	// - "MONTHLY" also requires fields "every" and "runsOnDayOfMonth" to be
	// set.
	Repeats string `json:"repeats,omitempty"`

	// RepeatsOnWeekDays: List of week days "WEEKLY" on which scheduled
	// reports should run.
	//
	// Possible values:
	//   "FRIDAY"
	//   "MONDAY"
	//   "SATURDAY"
	//   "SUNDAY"
	//   "THURSDAY"
	//   "TUESDAY"
	//   "WEDNESDAY"
	RepeatsOnWeekDays []string `json:"repeatsOnWeekDays,omitempty"`

	// RunsOnDayOfMonth: Enum to define for "MONTHLY" scheduled reports
	// whether reports should be repeated on the same day of the month as
	// "startDate" or the same day of the week of the month.
	// Example: If 'startDate' is Monday, April 2nd 2012 (2012-04-02),
	// "DAY_OF_MONTH" would run subsequent reports on the 2nd of every
	// Month, and "WEEK_OF_MONTH" would run subsequent reports on the first
	// Monday of the month.
	//
	// Possible values:
	//   "DAY_OF_MONTH"
	//   "WEEK_OF_MONTH"
	RunsOnDayOfMonth string `json:"runsOnDayOfMonth,omitempty"`

	// StartDate: Start date of date range for which scheduled reports
	// should be run.
	StartDate string `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Active") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportSchedule) MarshalJSON() ([]byte, error) {
	type noMethod ReportSchedule
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportCompatibleFields: Represents fields that are compatible to be
// selected for a report of type "STANDARD".
type ReportCompatibleFields struct {
	// DimensionFilters: Dimensions which are compatible to be selected in
	// the "dimensionFilters" section of the report.
	DimensionFilters []*Dimension `json:"dimensionFilters,omitempty"`

	// Dimensions: Dimensions which are compatible to be selected in the
	// "dimensions" section of the report.
	Dimensions []*Dimension `json:"dimensions,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#reportCompatibleFields.
	Kind string `json:"kind,omitempty"`

	// Metrics: Metrics which are compatible to be selected in the
	// "metricNames" section of the report.
	Metrics []*Metric `json:"metrics,omitempty"`

	// PivotedActivityMetrics: Metrics which are compatible to be selected
	// as activity metrics to pivot on in the "activities" section of the
	// report.
	PivotedActivityMetrics []*Metric `json:"pivotedActivityMetrics,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DimensionFilters") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportCompatibleFields) MarshalJSON() ([]byte, error) {
	type noMethod ReportCompatibleFields
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportList: Represents the list of reports.
type ReportList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The reports returned in this response.
	Items []*Report `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case dfareporting#reportList.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Continuation token used to page through reports. To
	// retrieve the next page of results, set the next request's "pageToken"
	// to the value of this field. The page token is only valid for a
	// limited amount of time and should not be persisted.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportList) MarshalJSON() ([]byte, error) {
	type noMethod ReportList
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ReportsConfiguration: Reporting Configuration
type ReportsConfiguration struct {
	// ExposureToConversionEnabled: Whether the exposure to conversion
	// report is enabled. This report shows detailed pathway information on
	// up to 10 of the most recent ad exposures seen by a user before
	// converting.
	ExposureToConversionEnabled bool `json:"exposureToConversionEnabled,omitempty"`

	// LookbackConfiguration: Default lookback windows for new advertisers
	// in this account.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// ReportGenerationTimeZoneId: Report generation time zone ID of this
	// account. This is a required field that can only be changed by a
	// superuser.
	// Acceptable values are:
	//
	// - "1" for "America/New_York"
	// - "2" for "Europe/London"
	// - "3" for "Europe/Paris"
	// - "4" for "Africa/Johannesburg"
	// - "5" for "Asia/Jerusalem"
	// - "6" for "Asia/Shanghai"
	// - "7" for "Asia/Hong_Kong"
	// - "8" for "Asia/Tokyo"
	// - "9" for "Australia/Sydney"
	// - "10" for "Asia/Dubai"
	// - "11" for "America/Los_Angeles"
	// - "12" for "Pacific/Auckland"
	// - "13" for "America/Sao_Paulo"
	ReportGenerationTimeZoneId int64 `json:"reportGenerationTimeZoneId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g.
	// "ExposureToConversionEnabled") to unconditionally include in API
	// requests. By default, fields with empty values are omitted from API
	// requests. However, any non-pointer, non-interface field appearing in
	// ForceSendFields will be sent to the server regardless of whether the
	// field is empty or not. This may be used to include empty fields in
	// Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ReportsConfiguration) MarshalJSON() ([]byte, error) {
	type noMethod ReportsConfiguration
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// RichMediaExitOverride: Rich Media Exit Override.
type RichMediaExitOverride struct {
	// CustomExitUrl: Click-through URL to override the default exit URL.
	// Applicable if the useCustomExitUrl field is set to true.
	CustomExitUrl string `json:"customExitUrl,omitempty"`

	// ExitId: ID for the override to refer to a specific exit in the
	// creative.
	ExitId int64 `json:"exitId,omitempty,string"`

	// UseCustomExitUrl: Whether to use the custom exit URL.
	UseCustomExitUrl bool `json:"useCustomExitUrl,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CustomExitUrl") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *RichMediaExitOverride) MarshalJSON() ([]byte, error) {
	type noMethod RichMediaExitOverride
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Site: Contains properties of a site.
type Site struct {
	// AccountId: Account ID of this site. This is a read-only field that
	// can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Approved: Whether this site is approved.
	Approved bool `json:"approved,omitempty"`

	// DirectorySiteId: Directory site associated with this site. This is a
	// required field that is read-only after insertion.
	DirectorySiteId int64 `json:"directorySiteId,omitempty,string"`

	// DirectorySiteIdDimensionValue: Dimension value for the ID of the
	// directory site. This is a read-only, auto-generated field.
	DirectorySiteIdDimensionValue *DimensionValue `json:"directorySiteIdDimensionValue,omitempty"`

	// Id: ID of this site. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// IdDimensionValue: Dimension value for the ID of this site. This is a
	// read-only, auto-generated field.
	IdDimensionValue *DimensionValue `json:"idDimensionValue,omitempty"`

	// KeyName: Key name of this site. This is a read-only, auto-generated
	// field.
	KeyName string `json:"keyName,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#site".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this site.This is a required field. Must be less than
	// 128 characters long. If this site is under a subaccount, the name
	// must be unique among sites of the same subaccount. Otherwise, this
	// site is a top-level site, and the name must be unique among top-level
	// sites of the same account.
	Name string `json:"name,omitempty"`

	// SiteContacts: Site contacts.
	SiteContacts []*SiteContact `json:"siteContacts,omitempty"`

	// SiteSettings: Site-wide settings.
	SiteSettings *SiteSettings `json:"siteSettings,omitempty"`

	// SubaccountId: Subaccount ID of this site. This is a read-only field
	// that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Site) MarshalJSON() ([]byte, error) {
	type noMethod Site
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SiteContact: Site Contact
type SiteContact struct {
	// ContactType: Site contact type.
	//
	// Possible values:
	//   "SALES_PERSON"
	//   "TRAFFICKER"
	ContactType string `json:"contactType,omitempty"`

	// Email: Email address of this site contact. This is a required field.
	Email string `json:"email,omitempty"`

	// FirstName: First name of this site contact.
	FirstName string `json:"firstName,omitempty"`

	// Id: ID of this site contact. This is a read-only, auto-generated
	// field.
	Id int64 `json:"id,omitempty,string"`

	// LastName: Last name of this site contact.
	LastName string `json:"lastName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ContactType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SiteContact) MarshalJSON() ([]byte, error) {
	type noMethod SiteContact
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SiteSettings: Site Settings
type SiteSettings struct {
	// ActiveViewOptOut: Whether active view creatives are disabled for this
	// site.
	ActiveViewOptOut bool `json:"activeViewOptOut,omitempty"`

	// CreativeSettings: Site-wide creative settings.
	CreativeSettings *CreativeSettings `json:"creativeSettings,omitempty"`

	// DisableBrandSafeAds: Whether brand safe ads are disabled for this
	// site.
	DisableBrandSafeAds bool `json:"disableBrandSafeAds,omitempty"`

	// DisableNewCookie: Whether new cookies are disabled for this site.
	DisableNewCookie bool `json:"disableNewCookie,omitempty"`

	// LookbackConfiguration: Lookback window settings for this site.
	LookbackConfiguration *LookbackConfiguration `json:"lookbackConfiguration,omitempty"`

	// TagSetting: Configuration settings for dynamic and image floodlight
	// tags.
	TagSetting *TagSetting `json:"tagSetting,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ActiveViewOptOut") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SiteSettings) MarshalJSON() ([]byte, error) {
	type noMethod SiteSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SitesListResponse: Site List Response
type SitesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#sitesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Sites: Site collection.
	Sites []*Site `json:"sites,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SitesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod SitesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Size: Represents the dimensions of ads, placements, creatives, or
// creative assets.
type Size struct {
	// Height: Height of this size.
	Height int64 `json:"height,omitempty"`

	// Iab: IAB standard size. This is a read-only, auto-generated field.
	Iab bool `json:"iab,omitempty"`

	// Id: ID of this size. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#size".
	Kind string `json:"kind,omitempty"`

	// Width: Width of this size.
	Width int64 `json:"width,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Height") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Size) MarshalJSON() ([]byte, error) {
	type noMethod Size
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SizesListResponse: Size List Response
type SizesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#sizesListResponse".
	Kind string `json:"kind,omitempty"`

	// Sizes: Size collection.
	Sizes []*Size `json:"sizes,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SizesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod SizesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SortedDimension: Represents a sorted dimension.
type SortedDimension struct {
	// Kind: The kind of resource this is, in this case
	// dfareporting#sortedDimension.
	Kind string `json:"kind,omitempty"`

	// Name: The name of the dimension.
	Name string `json:"name,omitempty"`

	// SortOrder: An optional sort order for the dimension column.
	//
	// Possible values:
	//   "ASCENDING"
	//   "DESCENDING"
	SortOrder string `json:"sortOrder,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SortedDimension) MarshalJSON() ([]byte, error) {
	type noMethod SortedDimension
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// Subaccount: Contains properties of a DCM subaccount.
type Subaccount struct {
	// AccountId: ID of the account that contains this subaccount. This is a
	// read-only field that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AvailablePermissionIds: IDs of the available user role permissions
	// for this subaccount.
	AvailablePermissionIds googleapi.Int64s `json:"availablePermissionIds,omitempty"`

	// Id: ID of this subaccount. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#subaccount".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this subaccount. This is a required field. Must be less
	// than 128 characters long and be unique among subaccounts of the same
	// account.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *Subaccount) MarshalJSON() ([]byte, error) {
	type noMethod Subaccount
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// SubaccountsListResponse: Subaccount List Response
type SubaccountsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#subaccountsListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// Subaccounts: Subaccount collection.
	Subaccounts []*Subaccount `json:"subaccounts,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *SubaccountsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod SubaccountsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// TagData: Placement Tag Data
type TagData struct {
	// AdId: Ad associated with this placement tag.
	AdId int64 `json:"adId,omitempty,string"`

	// ClickTag: Tag string to record a click.
	ClickTag string `json:"clickTag,omitempty"`

	// CreativeId: Creative associated with this placement tag.
	CreativeId int64 `json:"creativeId,omitempty,string"`

	// Format: TagData tag format of this tag.
	//
	// Possible values:
	//   "PLACEMENT_TAG_CLICK_COMMANDS"
	//   "PLACEMENT_TAG_IFRAME_ILAYER"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
	//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
	//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
	//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_JAVASCRIPT"
	//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
	//   "PLACEMENT_TAG_STANDARD"
	//   "PLACEMENT_TAG_TRACKING"
	//   "PLACEMENT_TAG_TRACKING_IFRAME"
	//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	Format string `json:"format,omitempty"`

	// ImpressionTag: Tag string for serving an ad.
	ImpressionTag string `json:"impressionTag,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *TagData) MarshalJSON() ([]byte, error) {
	type noMethod TagData
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// TagSetting: Tag Settings
type TagSetting struct {
	// AdditionalKeyValues: Additional key-values to be included in tags.
	// Each key-value pair must be of the form key=value, and pairs must be
	// separated by a semicolon (;). Keys and values must not contain
	// commas. For example, id=2;color=red is a valid value for this field.
	AdditionalKeyValues string `json:"additionalKeyValues,omitempty"`

	// IncludeClickThroughUrls: Whether static landing page URLs should be
	// included in the tags. This setting applies only to placements.
	IncludeClickThroughUrls bool `json:"includeClickThroughUrls,omitempty"`

	// IncludeClickTracking: Whether click-tracking string should be
	// included in the tags.
	IncludeClickTracking bool `json:"includeClickTracking,omitempty"`

	// KeywordOption: Option specifying how keywords are embedded in ad
	// tags. This setting can be used to specify whether keyword
	// placeholders are inserted in placement tags for this site. Publishers
	// can then add keywords to those placeholders.
	//
	// Possible values:
	//   "GENERATE_SEPARATE_TAG_FOR_EACH_KEYWORD"
	//   "IGNORE"
	//   "PLACEHOLDER_WITH_LIST_OF_KEYWORDS"
	KeywordOption string `json:"keywordOption,omitempty"`

	// ForceSendFields is a list of field names (e.g. "AdditionalKeyValues")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *TagSetting) MarshalJSON() ([]byte, error) {
	type noMethod TagSetting
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// TagSettings: Dynamic and Image Tag Settings.
type TagSettings struct {
	// DynamicTagEnabled: Whether dynamic floodlight tags are enabled.
	DynamicTagEnabled bool `json:"dynamicTagEnabled,omitempty"`

	// ImageTagEnabled: Whether image tags are enabled.
	ImageTagEnabled bool `json:"imageTagEnabled,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DynamicTagEnabled")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *TagSettings) MarshalJSON() ([]byte, error) {
	type noMethod TagSettings
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// TargetWindow: Target Window.
type TargetWindow struct {
	// CustomHtml: User-entered value.
	CustomHtml string `json:"customHtml,omitempty"`

	// TargetWindowOption: Type of browser window for which the backup image
	// of the flash creative can be displayed.
	//
	// Possible values:
	//   "CURRENT_WINDOW"
	//   "CUSTOM"
	//   "NEW_WINDOW"
	TargetWindowOption string `json:"targetWindowOption,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CustomHtml") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *TargetWindow) MarshalJSON() ([]byte, error) {
	type noMethod TargetWindow
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// TechnologyTargeting: Technology Targeting.
type TechnologyTargeting struct {
	// Browsers: Browsers that this ad targets. For each browser either set
	// browserVersionId or dartId along with the version numbers. If both
	// are specified, only browserVersionId will be used.The other fields
	// are populated automatically when the ad is inserted or updated.
	Browsers []*Browser `json:"browsers,omitempty"`

	// ConnectionTypes: Connection types that this ad targets. For each
	// connection type only id is required.The other fields are populated
	// automatically when the ad is inserted or updated.
	ConnectionTypes []*ConnectionType `json:"connectionTypes,omitempty"`

	// MobileCarriers: Mobile carriers that this ad targets. For each mobile
	// carrier only id is required, and the other fields are populated
	// automatically when the ad is inserted or updated. If targeting a
	// mobile carrier, do not set targeting for any zip codes.
	MobileCarriers []*MobileCarrier `json:"mobileCarriers,omitempty"`

	// OperatingSystemVersions: Operating system versions that this ad
	// targets. To target all versions, use operatingSystems. For each
	// operating system version, only id is required. The other fields are
	// populated automatically when the ad is inserted or updated. If
	// targeting an operating system version, do not set targeting for the
	// corresponding operating system in operatingSystems.
	OperatingSystemVersions []*OperatingSystemVersion `json:"operatingSystemVersions,omitempty"`

	// OperatingSystems: Operating systems that this ad targets. To target
	// specific versions, use operatingSystemVersions. For each operating
	// system only dartId is required. The other fields are populated
	// automatically when the ad is inserted or updated. If targeting an
	// operating system, do not set targeting for operating system versions
	// for the same operating system.
	OperatingSystems []*OperatingSystem `json:"operatingSystems,omitempty"`

	// PlatformTypes: Platform types that this ad targets. For example,
	// desktop, mobile, or tablet. For each platform type, only id is
	// required, and the other fields are populated automatically when the
	// ad is inserted or updated.
	PlatformTypes []*PlatformType `json:"platformTypes,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Browsers") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *TechnologyTargeting) MarshalJSON() ([]byte, error) {
	type noMethod TechnologyTargeting
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// ThirdPartyTrackingUrl: Third-party Tracking URL.
type ThirdPartyTrackingUrl struct {
	// ThirdPartyUrlType: Third-party URL type for in-stream video
	// creatives.
	//
	// Possible values:
	//   "CLICK_TRACKING"
	//   "IMPRESSION"
	//   "RICH_MEDIA_BACKUP_IMPRESSION"
	//   "RICH_MEDIA_IMPRESSION"
	//   "RICH_MEDIA_RM_IMPRESSION"
	//   "SURVEY"
	//   "VIDEO_COMPLETE"
	//   "VIDEO_CUSTOM"
	//   "VIDEO_FIRST_QUARTILE"
	//   "VIDEO_FULLSCREEN"
	//   "VIDEO_MIDPOINT"
	//   "VIDEO_MUTE"
	//   "VIDEO_PAUSE"
	//   "VIDEO_PROGRESS"
	//   "VIDEO_REWIND"
	//   "VIDEO_SKIP"
	//   "VIDEO_START"
	//   "VIDEO_STOP"
	//   "VIDEO_THIRD_QUARTILE"
	ThirdPartyUrlType string `json:"thirdPartyUrlType,omitempty"`

	// Url: URL for the specified third-party URL type.
	Url string `json:"url,omitempty"`

	// ForceSendFields is a list of field names (e.g. "ThirdPartyUrlType")
	// to unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *ThirdPartyTrackingUrl) MarshalJSON() ([]byte, error) {
	type noMethod ThirdPartyTrackingUrl
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserDefinedVariableConfiguration: User Defined Variable
// configuration.
type UserDefinedVariableConfiguration struct {
	// DataType: Data type for the variable. This is a required field.
	//
	// Possible values:
	//   "NUMBER"
	//   "STRING"
	DataType string `json:"dataType,omitempty"`

	// ReportName: User-friendly name for the variable which will appear in
	// reports. This is a required field, must be less than 64 characters
	// long, and cannot contain the following characters: ""<>".
	ReportName string `json:"reportName,omitempty"`

	// VariableType: Variable name in the tag. This is a required field.
	//
	// Possible values:
	//   "U1"
	//   "U10"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U2"
	//   "U20"
	//   "U3"
	//   "U4"
	//   "U5"
	//   "U6"
	//   "U7"
	//   "U8"
	//   "U9"
	VariableType string `json:"variableType,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DataType") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserDefinedVariableConfiguration) MarshalJSON() ([]byte, error) {
	type noMethod UserDefinedVariableConfiguration
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserProfile: Represents a UserProfile resource.
type UserProfile struct {
	// AccountId: The account ID to which this profile belongs.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AccountName: The account name this profile belongs to.
	AccountName string `json:"accountName,omitempty"`

	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Kind: The kind of resource this is, in this case
	// dfareporting#userProfile.
	Kind string `json:"kind,omitempty"`

	// ProfileId: The unique ID of the user profile.
	ProfileId int64 `json:"profileId,omitempty,string"`

	// SubAccountId: The sub account ID this profile belongs to if
	// applicable.
	SubAccountId int64 `json:"subAccountId,omitempty,string"`

	// SubAccountName: The sub account name this profile belongs to if
	// applicable.
	SubAccountName string `json:"subAccountName,omitempty"`

	// UserName: The user name.
	UserName string `json:"userName,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserProfile) MarshalJSON() ([]byte, error) {
	type noMethod UserProfile
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserProfileList: Represents the list of user profiles.
type UserProfileList struct {
	// Etag: The eTag of this response for caching purposes.
	Etag string `json:"etag,omitempty"`

	// Items: The user profiles returned in this response.
	Items []*UserProfile `json:"items,omitempty"`

	// Kind: The kind of list this is, in this case
	// dfareporting#userProfileList.
	Kind string `json:"kind,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Etag") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserProfileList) MarshalJSON() ([]byte, error) {
	type noMethod UserProfileList
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRole: Contains properties of auser role, which is used to manage
// user access.
type UserRole struct {
	// AccountId: Account ID of this user role. This is a read-only field
	// that can be left blank.
	AccountId int64 `json:"accountId,omitempty,string"`

	// DefaultUserRole: Whether this is a default user role. Default user
	// roles are created by the system for the account/subaccount and cannot
	// be modified or deleted. Each default user role comes with a basic set
	// of preassigned permissions.
	DefaultUserRole bool `json:"defaultUserRole,omitempty"`

	// Id: ID of this user role. This is a read-only, auto-generated field.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRole".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role. This is a required field. Must be less
	// than 256 characters long. If this user role is under a subaccount,
	// the name must be unique among sites of the same subaccount.
	// Otherwise, this user role is a top-level user role, and the name must
	// be unique among top-level user roles of the same account.
	Name string `json:"name,omitempty"`

	// ParentUserRoleId: ID of the user role that this user role is based on
	// or copied from. This is a required field.
	ParentUserRoleId int64 `json:"parentUserRoleId,omitempty,string"`

	// Permissions: List of permissions associated with this user role.
	Permissions []*UserRolePermission `json:"permissions,omitempty"`

	// SubaccountId: Subaccount ID of this user role. This is a read-only
	// field that can be left blank.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "AccountId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRole) MarshalJSON() ([]byte, error) {
	type noMethod UserRole
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRolePermission: Contains properties of a user role permission.
type UserRolePermission struct {
	// Availability: Levels of availability for a user role permission.
	//
	// Possible values:
	//   "ACCOUNT_ALWAYS"
	//   "ACCOUNT_BY_DEFAULT"
	//   "NOT_AVAILABLE_BY_DEFAULT"
	//   "SUBACCOUNT_AND_ACCOUNT_ALWAYS"
	//   "SUBACCOUNT_AND_ACCOUNT_BY_DEFAULT"
	Availability string `json:"availability,omitempty"`

	// Id: ID of this user role permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermission".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role permission.
	Name string `json:"name,omitempty"`

	// PermissionGroupId: ID of the permission group that this user role
	// permission belongs to.
	PermissionGroupId int64 `json:"permissionGroupId,omitempty,string"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Availability") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRolePermission) MarshalJSON() ([]byte, error) {
	type noMethod UserRolePermission
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRolePermissionGroup: Represents a grouping of related user role
// permissions.
type UserRolePermissionGroup struct {
	// Id: ID of this user role permission.
	Id int64 `json:"id,omitempty,string"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionGroup".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this user role permission group.
	Name string `json:"name,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Id") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRolePermissionGroup) MarshalJSON() ([]byte, error) {
	type noMethod UserRolePermissionGroup
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRolePermissionGroupsListResponse: User Role Permission Group List
// Response
type UserRolePermissionGroupsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionGroupsListResponse".
	Kind string `json:"kind,omitempty"`

	// UserRolePermissionGroups: User role permission group collection.
	UserRolePermissionGroups []*UserRolePermissionGroup `json:"userRolePermissionGroups,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRolePermissionGroupsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod UserRolePermissionGroupsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRolePermissionsListResponse: User Role Permission List Response
type UserRolePermissionsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolePermissionsListResponse".
	Kind string `json:"kind,omitempty"`

	// UserRolePermissions: User role permission collection.
	UserRolePermissions []*UserRolePermission `json:"userRolePermissions,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRolePermissionsListResponse) MarshalJSON() ([]byte, error) {
	type noMethod UserRolePermissionsListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// UserRolesListResponse: User Role List Response
type UserRolesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#userRolesListResponse".
	Kind string `json:"kind,omitempty"`

	// NextPageToken: Pagination token to be used for the next list
	// operation.
	NextPageToken string `json:"nextPageToken,omitempty"`

	// UserRoles: User role collection.
	UserRoles []*UserRole `json:"userRoles,omitempty"`

	// ServerResponse contains the HTTP response code and headers from the
	// server.
	googleapi.ServerResponse `json:"-"`

	// ForceSendFields is a list of field names (e.g. "Kind") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// server regardless of whether the field is empty or not. This may be
	// used to include empty fields in Patch requests.
	ForceSendFields []string `json:"-"`
}

func (s *UserRolesListResponse) MarshalJSON() ([]byte, error) {
	type noMethod UserRolesListResponse
	raw := noMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields)
}

// method id "dfareporting.accountActiveAdSummaries.get":

type AccountActiveAdSummariesGetCall struct {
	s                *Service
	profileId        int64
	summaryAccountId int64
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
}

// Get: Gets the account's active ad summary by account ID.
func (r *AccountActiveAdSummariesService) Get(profileId int64, summaryAccountId int64) *AccountActiveAdSummariesGetCall {
	c := &AccountActiveAdSummariesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.summaryAccountId = summaryAccountId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountActiveAdSummariesGetCall) Fields(s ...googleapi.Field) *AccountActiveAdSummariesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountActiveAdSummariesGetCall) IfNoneMatch(entityTag string) *AccountActiveAdSummariesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountActiveAdSummariesGetCall) Context(ctx context.Context) *AccountActiveAdSummariesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountActiveAdSummariesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountActiveAdSummaries/{summaryAccountId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":        strconv.FormatInt(c.profileId, 10),
		"summaryAccountId": strconv.FormatInt(c.summaryAccountId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountActiveAdSummaries.get" call.
// Exactly one of *AccountActiveAdSummary or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountActiveAdSummary.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountActiveAdSummariesGetCall) Do(opts ...googleapi.CallOption) (*AccountActiveAdSummary, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountActiveAdSummary{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets the account's active ad summary by account ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountActiveAdSummaries.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "summaryAccountId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "summaryAccountId": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountActiveAdSummaries/{summaryAccountId}",
	//   "response": {
	//     "$ref": "AccountActiveAdSummary"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissionGroups.get":

type AccountPermissionGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one account permission group by ID.
func (r *AccountPermissionGroupsService) Get(profileId int64, id int64) *AccountPermissionGroupsGetCall {
	c := &AccountPermissionGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionGroupsGetCall) Fields(s ...googleapi.Field) *AccountPermissionGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountPermissionGroupsGetCall) IfNoneMatch(entityTag string) *AccountPermissionGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountPermissionGroupsGetCall) Context(ctx context.Context) *AccountPermissionGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountPermissionGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountPermissionGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountPermissionGroups.get" call.
// Exactly one of *AccountPermissionGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountPermissionGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionGroupsGetCall) Do(opts ...googleapi.CallOption) (*AccountPermissionGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one account permission group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissionGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account permission group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissionGroups/{id}",
	//   "response": {
	//     "$ref": "AccountPermissionGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissionGroups.list":

type AccountPermissionGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves the list of account permission groups.
func (r *AccountPermissionGroupsService) List(profileId int64) *AccountPermissionGroupsListCall {
	c := &AccountPermissionGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionGroupsListCall) Fields(s ...googleapi.Field) *AccountPermissionGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountPermissionGroupsListCall) IfNoneMatch(entityTag string) *AccountPermissionGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountPermissionGroupsListCall) Context(ctx context.Context) *AccountPermissionGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountPermissionGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountPermissionGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountPermissionGroups.list" call.
// Exactly one of *AccountPermissionGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountPermissionGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AccountPermissionGroupsListCall) Do(opts ...googleapi.CallOption) (*AccountPermissionGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of account permission groups.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissionGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissionGroups",
	//   "response": {
	//     "$ref": "AccountPermissionGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissions.get":

type AccountPermissionsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one account permission by ID.
func (r *AccountPermissionsService) Get(profileId int64, id int64) *AccountPermissionsGetCall {
	c := &AccountPermissionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionsGetCall) Fields(s ...googleapi.Field) *AccountPermissionsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountPermissionsGetCall) IfNoneMatch(entityTag string) *AccountPermissionsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountPermissionsGetCall) Context(ctx context.Context) *AccountPermissionsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountPermissionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountPermissions/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountPermissions.get" call.
// Exactly one of *AccountPermission or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountPermission.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionsGetCall) Do(opts ...googleapi.CallOption) (*AccountPermission, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermission{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one account permission by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account permission ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissions/{id}",
	//   "response": {
	//     "$ref": "AccountPermission"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountPermissions.list":

type AccountPermissionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves the list of account permissions.
func (r *AccountPermissionsService) List(profileId int64) *AccountPermissionsListCall {
	c := &AccountPermissionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountPermissionsListCall) Fields(s ...googleapi.Field) *AccountPermissionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountPermissionsListCall) IfNoneMatch(entityTag string) *AccountPermissionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountPermissionsListCall) Context(ctx context.Context) *AccountPermissionsListCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountPermissionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountPermissions")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountPermissions.list" call.
// Exactly one of *AccountPermissionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountPermissionsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountPermissionsListCall) Do(opts ...googleapi.CallOption) (*AccountPermissionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountPermissionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of account permissions.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountPermissions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountPermissions",
	//   "response": {
	//     "$ref": "AccountPermissionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.get":

type AccountUserProfilesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one account user profile by ID.
func (r *AccountUserProfilesService) Get(profileId int64, id int64) *AccountUserProfilesGetCall {
	c := &AccountUserProfilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesGetCall) Fields(s ...googleapi.Field) *AccountUserProfilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountUserProfilesGetCall) IfNoneMatch(entityTag string) *AccountUserProfilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountUserProfilesGetCall) Context(ctx context.Context) *AccountUserProfilesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountUserProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountUserProfiles/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountUserProfiles.get" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesGetCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one account user profile by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountUserProfiles.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles/{id}",
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.list":

type AccountUserProfilesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of account user profiles, possibly filtered.
func (r *AccountUserProfilesService) List(profileId int64) *AccountUserProfilesListCall {
	c := &AccountUserProfilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active user
// profiles.
func (c *AccountUserProfilesListCall) Active(active bool) *AccountUserProfilesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// Ids sets the optional parameter "ids": Select only user profiles with
// these IDs.
func (c *AccountUserProfilesListCall) Ids(ids ...int64) *AccountUserProfilesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AccountUserProfilesListCall) MaxResults(maxResults int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AccountUserProfilesListCall) PageToken(pageToken string) *AccountUserProfilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or email. Wildcards (*) are
// allowed. For example, "user profile*2015" will return objects with
// names like "user profile June 2015", "user profile April 2015", or
// simply "user profile 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "user profile" will match objects with
// name "my user profile", "user profile 2015", or simply "user
// profile".
func (c *AccountUserProfilesListCall) SearchString(searchString string) *AccountUserProfilesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *AccountUserProfilesListCall) SortField(sortField string) *AccountUserProfilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *AccountUserProfilesListCall) SortOrder(sortOrder string) *AccountUserProfilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// user profiles with the specified subaccount ID.
func (c *AccountUserProfilesListCall) SubaccountId(subaccountId int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// UserRoleId sets the optional parameter "userRoleId": Select only user
// profiles with the specified user role ID.
func (c *AccountUserProfilesListCall) UserRoleId(userRoleId int64) *AccountUserProfilesListCall {
	c.urlParams_.Set("userRoleId", fmt.Sprint(userRoleId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesListCall) Fields(s ...googleapi.Field) *AccountUserProfilesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountUserProfilesListCall) IfNoneMatch(entityTag string) *AccountUserProfilesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountUserProfilesListCall) Context(ctx context.Context) *AccountUserProfilesListCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountUserProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountUserProfiles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountUserProfiles.list" call.
// Exactly one of *AccountUserProfilesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AccountUserProfilesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesListCall) Do(opts ...googleapi.CallOption) (*AccountUserProfilesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfilesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of account user profiles, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accountUserProfiles.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active user profiles.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only user profiles with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or email. Wildcards (*) are allowed. For example, \"user profile*2015\" will return objects with names like \"user profile June 2015\", \"user profile April 2015\", or simply \"user profile 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"user profile\" will match objects with name \"my user profile\", \"user profile 2015\", or simply \"user profile\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only user profiles with the specified subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userRoleId": {
	//       "description": "Select only user profiles with the specified user role ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "response": {
	//     "$ref": "AccountUserProfilesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountUserProfilesListCall) Pages(ctx context.Context, f func(*AccountUserProfilesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.accountUserProfiles.patch":

type AccountUserProfilesPatchCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Patch: Updates an existing account user profile. This method supports
// patch semantics.
func (r *AccountUserProfilesService) Patch(profileId int64, id int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesPatchCall {
	c := &AccountUserProfilesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.accountuserprofile = accountuserprofile
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesPatchCall) Fields(s ...googleapi.Field) *AccountUserProfilesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountUserProfilesPatchCall) Context(ctx context.Context) *AccountUserProfilesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountUserProfilesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.accountuserprofile)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountUserProfiles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountUserProfiles.patch" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesPatchCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing account user profile. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.accountUserProfiles.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User profile ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "request": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accountUserProfiles.update":

type AccountUserProfilesUpdateCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Update: Updates an existing account user profile.
func (r *AccountUserProfilesService) Update(profileId int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesUpdateCall {
	c := &AccountUserProfilesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.accountuserprofile = accountuserprofile
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountUserProfilesUpdateCall) Fields(s ...googleapi.Field) *AccountUserProfilesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountUserProfilesUpdateCall) Context(ctx context.Context) *AccountUserProfilesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountUserProfilesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.accountuserprofile)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accountUserProfiles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accountUserProfiles.update" call.
// Exactly one of *AccountUserProfile or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountUserProfile.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountUserProfilesUpdateCall) Do(opts ...googleapi.CallOption) (*AccountUserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountUserProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing account user profile.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.accountUserProfiles.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accountUserProfiles",
	//   "request": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "response": {
	//     "$ref": "AccountUserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.get":

type AccountsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one account by ID.
func (r *AccountsService) Get(profileId int64, id int64) *AccountsGetCall {
	c := &AccountsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsGetCall) Fields(s ...googleapi.Field) *AccountsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsGetCall) IfNoneMatch(entityTag string) *AccountsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsGetCall) Context(ctx context.Context) *AccountsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accounts/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accounts.get" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsGetCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one account by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accounts.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts/{id}",
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.list":

type AccountsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves the list of accounts, possibly filtered.
func (r *AccountsService) List(profileId int64) *AccountsListCall {
	c := &AccountsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active
// accounts. Don't set this field to select both active and non-active
// accounts.
func (c *AccountsListCall) Active(active bool) *AccountsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// Ids sets the optional parameter "ids": Select only accounts with
// these IDs.
func (c *AccountsListCall) Ids(ids ...int64) *AccountsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AccountsListCall) MaxResults(maxResults int64) *AccountsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AccountsListCall) PageToken(pageToken string) *AccountsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "account*2015" will return objects with names like "account
// June 2015", "account April 2015", or simply "account 2015". Most of
// the searches also add wildcards implicitly at the start and the end
// of the search string. For example, a search string of "account" will
// match objects with name "my account", "account 2015", or simply
// "account".
func (c *AccountsListCall) SearchString(searchString string) *AccountsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *AccountsListCall) SortField(sortField string) *AccountsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *AccountsListCall) SortOrder(sortOrder string) *AccountsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsListCall) Fields(s ...googleapi.Field) *AccountsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AccountsListCall) IfNoneMatch(entityTag string) *AccountsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsListCall) Context(ctx context.Context) *AccountsListCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accounts.list" call.
// Exactly one of *AccountsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AccountsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AccountsListCall) Do(opts ...googleapi.CallOption) (*AccountsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AccountsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of accounts, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.accounts.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active accounts. Don't set this field to select both active and non-active accounts.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only accounts with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"account*2015\" will return objects with names like \"account June 2015\", \"account April 2015\", or simply \"account 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"account\" will match objects with name \"my account\", \"account 2015\", or simply \"account\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "response": {
	//     "$ref": "AccountsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AccountsListCall) Pages(ctx context.Context, f func(*AccountsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.accounts.patch":

type AccountsPatchCall struct {
	s          *Service
	profileId  int64
	account    *Account
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing account. This method supports patch
// semantics.
func (r *AccountsService) Patch(profileId int64, id int64, account *Account) *AccountsPatchCall {
	c := &AccountsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.account = account
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsPatchCall) Fields(s ...googleapi.Field) *AccountsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsPatchCall) Context(ctx context.Context) *AccountsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.account)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accounts.patch" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsPatchCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing account. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.accounts.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Account ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "request": {
	//     "$ref": "Account"
	//   },
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.accounts.update":

type AccountsUpdateCall struct {
	s          *Service
	profileId  int64
	account    *Account
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing account.
func (r *AccountsService) Update(profileId int64, account *Account) *AccountsUpdateCall {
	c := &AccountsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.account = account
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AccountsUpdateCall) Fields(s ...googleapi.Field) *AccountsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AccountsUpdateCall) Context(ctx context.Context) *AccountsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *AccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.account)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/accounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.accounts.update" call.
// Exactly one of *Account or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Account.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *AccountsUpdateCall) Do(opts ...googleapi.CallOption) (*Account, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Account{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing account.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.accounts.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/accounts",
	//   "request": {
	//     "$ref": "Account"
	//   },
	//   "response": {
	//     "$ref": "Account"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.get":

type AdsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one ad by ID.
func (r *AdsService) Get(profileId int64, id int64) *AdsGetCall {
	c := &AdsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsGetCall) Fields(s ...googleapi.Field) *AdsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdsGetCall) IfNoneMatch(entityTag string) *AdsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdsGetCall) Context(ctx context.Context) *AdsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AdsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/ads/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.get" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsGetCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one ad by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.ads.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Ad ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads/{id}",
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.insert":

type AdsInsertCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new ad.
func (r *AdsService) Insert(profileId int64, ad *Ad) *AdsInsertCall {
	c := &AdsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.ad = ad
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsInsertCall) Fields(s ...googleapi.Field) *AdsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdsInsertCall) Context(ctx context.Context) *AdsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *AdsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.ad)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/ads")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.insert" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsInsertCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new ad.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.ads.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.list":

type AdsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of ads, possibly filtered.
func (r *AdsService) List(profileId int64) *AdsListCall {
	c := &AdsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active ads.
func (c *AdsListCall) Active(active bool) *AdsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// ads with this advertiser ID.
func (c *AdsListCall) AdvertiserId(advertiserId int64) *AdsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// ads.
func (c *AdsListCall) Archived(archived bool) *AdsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// AudienceSegmentIds sets the optional parameter "audienceSegmentIds":
// Select only ads with these audience segment IDs.
func (c *AdsListCall) AudienceSegmentIds(audienceSegmentIds ...int64) *AdsListCall {
	var audienceSegmentIds_ []string
	for _, v := range audienceSegmentIds {
		audienceSegmentIds_ = append(audienceSegmentIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("audienceSegmentIds", audienceSegmentIds_)
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// ads with these campaign IDs.
func (c *AdsListCall) CampaignIds(campaignIds ...int64) *AdsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// Compatibility sets the optional parameter "compatibility": Select
// default ads with the specified compatibility. Applicable when type is
// AD_SERVING_DEFAULT_AD. WEB and WEB_INTERSTITIAL refer to rendering
// either on desktop or on mobile devices for regular or interstitial
// ads, respectively. APP and APP_INTERSTITIAL are for rendering in
// mobile apps. IN_STREAM_VIDEO refers to rendering an in-stream video
// ads developed with the VAST standard.
//
// Possible values:
//   "APP"
//   "APP_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
//   "WEB"
//   "WEB_INTERSTITIAL"
func (c *AdsListCall) Compatibility(compatibility string) *AdsListCall {
	c.urlParams_.Set("compatibility", compatibility)
	return c
}

// CreativeIds sets the optional parameter "creativeIds": Select only
// ads with these creative IDs assigned.
func (c *AdsListCall) CreativeIds(creativeIds ...int64) *AdsListCall {
	var creativeIds_ []string
	for _, v := range creativeIds {
		creativeIds_ = append(creativeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeIds", creativeIds_)
	return c
}

// CreativeOptimizationConfigurationIds sets the optional parameter
// "creativeOptimizationConfigurationIds": Select only ads with these
// creative optimization configuration IDs.
func (c *AdsListCall) CreativeOptimizationConfigurationIds(creativeOptimizationConfigurationIds ...int64) *AdsListCall {
	var creativeOptimizationConfigurationIds_ []string
	for _, v := range creativeOptimizationConfigurationIds {
		creativeOptimizationConfigurationIds_ = append(creativeOptimizationConfigurationIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeOptimizationConfigurationIds", creativeOptimizationConfigurationIds_)
	return c
}

// CreativeType sets the optional parameter "creativeType": Select only
// ads with the specified creativeType.
//
// Possible values:
//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
//   "CUSTOM_INPAGE"
//   "CUSTOM_INTERSTITIAL"
//   "ENHANCED_BANNER"
//   "ENHANCED_IMAGE"
//   "FLASH_INPAGE"
//   "HTML5_BANNER"
//   "IMAGE"
//   "INSTREAM_VIDEO"
//   "INTERNAL_REDIRECT"
//   "INTERSTITIAL_INTERNAL_REDIRECT"
//   "REDIRECT"
//   "RICH_MEDIA_EXPANDING"
//   "RICH_MEDIA_IM_EXPAND"
//   "RICH_MEDIA_INPAGE"
//   "RICH_MEDIA_INPAGE_FLOATING"
//   "RICH_MEDIA_INTERSTITIAL_FLOAT"
//   "RICH_MEDIA_MOBILE_IN_APP"
//   "RICH_MEDIA_MULTI_FLOATING"
//   "RICH_MEDIA_PEEL_DOWN"
//   "TRACKING_TEXT"
//   "VAST_REDIRECT"
//   "VPAID_LINEAR"
//   "VPAID_NON_LINEAR"
func (c *AdsListCall) CreativeType(creativeType string) *AdsListCall {
	c.urlParams_.Set("creativeType", creativeType)
	return c
}

// DynamicClickTracker sets the optional parameter
// "dynamicClickTracker": Select only dynamic click trackers. Applicable
// when type is AD_SERVING_CLICK_TRACKER. If true, select dynamic click
// trackers. If false, select static click trackers. Leave unset to
// select both.
func (c *AdsListCall) DynamicClickTracker(dynamicClickTracker bool) *AdsListCall {
	c.urlParams_.Set("dynamicClickTracker", fmt.Sprint(dynamicClickTracker))
	return c
}

// Ids sets the optional parameter "ids": Select only ads with these
// IDs.
func (c *AdsListCall) Ids(ids ...int64) *AdsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// LandingPageIds sets the optional parameter "landingPageIds": Select
// only ads with these landing page IDs.
func (c *AdsListCall) LandingPageIds(landingPageIds ...int64) *AdsListCall {
	var landingPageIds_ []string
	for _, v := range landingPageIds {
		landingPageIds_ = append(landingPageIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("landingPageIds", landingPageIds_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdsListCall) MaxResults(maxResults int64) *AdsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OverriddenEventTagId sets the optional parameter
// "overriddenEventTagId": Select only ads with this event tag override
// ID.
func (c *AdsListCall) OverriddenEventTagId(overriddenEventTagId int64) *AdsListCall {
	c.urlParams_.Set("overriddenEventTagId", fmt.Sprint(overriddenEventTagId))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdsListCall) PageToken(pageToken string) *AdsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PlacementIds sets the optional parameter "placementIds": Select only
// ads with these placement IDs assigned.
func (c *AdsListCall) PlacementIds(placementIds ...int64) *AdsListCall {
	var placementIds_ []string
	for _, v := range placementIds {
		placementIds_ = append(placementIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementIds", placementIds_)
	return c
}

// RemarketingListIds sets the optional parameter "remarketingListIds":
// Select only ads whose list targeting expression use these remarketing
// list IDs.
func (c *AdsListCall) RemarketingListIds(remarketingListIds ...int64) *AdsListCall {
	var remarketingListIds_ []string
	for _, v := range remarketingListIds {
		remarketingListIds_ = append(remarketingListIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("remarketingListIds", remarketingListIds_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "ad*2015" will return objects with names like "ad June
// 2015", "ad April 2015", or simply "ad 2015". Most of the searches
// also add wildcards implicitly at the start and the end of the search
// string. For example, a search string of "ad" will match objects with
// name "my ad", "ad 2015", or simply "ad".
func (c *AdsListCall) SearchString(searchString string) *AdsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only ads with
// these size IDs.
func (c *AdsListCall) SizeIds(sizeIds ...int64) *AdsListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *AdsListCall) SortField(sortField string) *AdsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *AdsListCall) SortOrder(sortOrder string) *AdsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SslCompliant sets the optional parameter "sslCompliant": Select only
// ads that are SSL-compliant.
func (c *AdsListCall) SslCompliant(sslCompliant bool) *AdsListCall {
	c.urlParams_.Set("sslCompliant", fmt.Sprint(sslCompliant))
	return c
}

// SslRequired sets the optional parameter "sslRequired": Select only
// ads that require SSL.
func (c *AdsListCall) SslRequired(sslRequired bool) *AdsListCall {
	c.urlParams_.Set("sslRequired", fmt.Sprint(sslRequired))
	return c
}

// Type sets the optional parameter "type": Select only ads with these
// types.
//
// Possible values:
//   "AD_SERVING_CLICK_TRACKER"
//   "AD_SERVING_DEFAULT_AD"
//   "AD_SERVING_STANDARD_AD"
//   "AD_SERVING_TRACKING"
func (c *AdsListCall) Type(type_ ...string) *AdsListCall {
	c.urlParams_.SetMulti("type", append([]string{}, type_...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsListCall) Fields(s ...googleapi.Field) *AdsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdsListCall) IfNoneMatch(entityTag string) *AdsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdsListCall) Context(ctx context.Context) *AdsListCall {
	c.ctx_ = ctx
	return c
}

func (c *AdsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/ads")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.list" call.
// Exactly one of *AdsListResponse or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdsListResponse.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdsListCall) Do(opts ...googleapi.CallOption) (*AdsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of ads, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.ads.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active ads.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only ads with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived ads.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "audienceSegmentIds": {
	//       "description": "Select only ads with these audience segment IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "campaignIds": {
	//       "description": "Select only ads with these campaign IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "compatibility": {
	//       "description": "Select default ads with the specified compatibility. Applicable when type is AD_SERVING_DEFAULT_AD. WEB and WEB_INTERSTITIAL refer to rendering either on desktop or on mobile devices for regular or interstitial ads, respectively. APP and APP_INTERSTITIAL are for rendering in mobile apps. IN_STREAM_VIDEO refers to rendering an in-stream video ads developed with the VAST standard.",
	//       "enum": [
	//         "APP",
	//         "APP_INTERSTITIAL",
	//         "IN_STREAM_VIDEO",
	//         "WEB",
	//         "WEB_INTERSTITIAL"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "creativeIds": {
	//       "description": "Select only ads with these creative IDs assigned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "creativeOptimizationConfigurationIds": {
	//       "description": "Select only ads with these creative optimization configuration IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "creativeType": {
	//       "description": "Select only ads with the specified creativeType.",
	//       "enum": [
	//         "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO",
	//         "CUSTOM_INPAGE",
	//         "CUSTOM_INTERSTITIAL",
	//         "ENHANCED_BANNER",
	//         "ENHANCED_IMAGE",
	//         "FLASH_INPAGE",
	//         "HTML5_BANNER",
	//         "IMAGE",
	//         "INSTREAM_VIDEO",
	//         "INTERNAL_REDIRECT",
	//         "INTERSTITIAL_INTERNAL_REDIRECT",
	//         "REDIRECT",
	//         "RICH_MEDIA_EXPANDING",
	//         "RICH_MEDIA_IM_EXPAND",
	//         "RICH_MEDIA_INPAGE",
	//         "RICH_MEDIA_INPAGE_FLOATING",
	//         "RICH_MEDIA_INTERSTITIAL_FLOAT",
	//         "RICH_MEDIA_MOBILE_IN_APP",
	//         "RICH_MEDIA_MULTI_FLOATING",
	//         "RICH_MEDIA_PEEL_DOWN",
	//         "TRACKING_TEXT",
	//         "VAST_REDIRECT",
	//         "VPAID_LINEAR",
	//         "VPAID_NON_LINEAR"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "dynamicClickTracker": {
	//       "description": "Select only dynamic click trackers. Applicable when type is AD_SERVING_CLICK_TRACKER. If true, select dynamic click trackers. If false, select static click trackers. Leave unset to select both.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only ads with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "landingPageIds": {
	//       "description": "Select only ads with these landing page IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "overriddenEventTagId": {
	//       "description": "Select only ads with this event tag override ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementIds": {
	//       "description": "Select only ads with these placement IDs assigned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListIds": {
	//       "description": "Select only ads whose list targeting expression use these remarketing list IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"ad*2015\" will return objects with names like \"ad June 2015\", \"ad April 2015\", or simply \"ad 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"ad\" will match objects with name \"my ad\", \"ad 2015\", or simply \"ad\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only ads with these size IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sslCompliant": {
	//       "description": "Select only ads that are SSL-compliant.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "sslRequired": {
	//       "description": "Select only ads that require SSL.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "type": {
	//       "description": "Select only ads with these types.",
	//       "enum": [
	//         "AD_SERVING_CLICK_TRACKER",
	//         "AD_SERVING_DEFAULT_AD",
	//         "AD_SERVING_STANDARD_AD",
	//         "AD_SERVING_TRACKING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "response": {
	//     "$ref": "AdsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AdsListCall) Pages(ctx context.Context, f func(*AdsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.ads.patch":

type AdsPatchCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing ad. This method supports patch semantics.
func (r *AdsService) Patch(profileId int64, id int64, ad *Ad) *AdsPatchCall {
	c := &AdsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.ad = ad
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsPatchCall) Fields(s ...googleapi.Field) *AdsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdsPatchCall) Context(ctx context.Context) *AdsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *AdsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.ad)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/ads")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.patch" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsPatchCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing ad. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.ads.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Ad ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.ads.update":

type AdsUpdateCall struct {
	s          *Service
	profileId  int64
	ad         *Ad
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing ad.
func (r *AdsService) Update(profileId int64, ad *Ad) *AdsUpdateCall {
	c := &AdsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.ad = ad
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdsUpdateCall) Fields(s ...googleapi.Field) *AdsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdsUpdateCall) Context(ctx context.Context) *AdsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *AdsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.ad)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/ads")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.ads.update" call.
// Exactly one of *Ad or error will be non-nil. Any non-2xx status code
// is an error. Response headers are in either *Ad.ServerResponse.Header
// or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *AdsUpdateCall) Do(opts ...googleapi.CallOption) (*Ad, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Ad{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing ad.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.ads.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/ads",
	//   "request": {
	//     "$ref": "Ad"
	//   },
	//   "response": {
	//     "$ref": "Ad"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.delete":

type AdvertiserGroupsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing advertiser group.
func (r *AdvertiserGroupsService) Delete(profileId int64, id int64) *AdvertiserGroupsDeleteCall {
	c := &AdvertiserGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsDeleteCall) Fields(s ...googleapi.Field) *AdvertiserGroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsDeleteCall) Context(ctx context.Context) *AdvertiserGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.delete" call.
func (c *AdvertiserGroupsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing advertiser group.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.advertiserGroups.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.get":

type AdvertiserGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one advertiser group by ID.
func (r *AdvertiserGroupsService) Get(profileId int64, id int64) *AdvertiserGroupsGetCall {
	c := &AdvertiserGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsGetCall) Fields(s ...googleapi.Field) *AdvertiserGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdvertiserGroupsGetCall) IfNoneMatch(entityTag string) *AdvertiserGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsGetCall) Context(ctx context.Context) *AdvertiserGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.get" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsGetCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one advertiser group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups/{id}",
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.insert":

type AdvertiserGroupsInsertCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Insert: Inserts a new advertiser group.
func (r *AdvertiserGroupsService) Insert(profileId int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsInsertCall {
	c := &AdvertiserGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertisergroup = advertisergroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsInsertCall) Fields(s ...googleapi.Field) *AdvertiserGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsInsertCall) Context(ctx context.Context) *AdvertiserGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertisergroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.insert" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsInsertCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new advertiser group.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.advertiserGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.list":

type AdvertiserGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of advertiser groups, possibly filtered.
func (r *AdvertiserGroupsService) List(profileId int64) *AdvertiserGroupsListCall {
	c := &AdvertiserGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only advertiser groups
// with these IDs.
func (c *AdvertiserGroupsListCall) Ids(ids ...int64) *AdvertiserGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdvertiserGroupsListCall) MaxResults(maxResults int64) *AdvertiserGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdvertiserGroupsListCall) PageToken(pageToken string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "advertiser*2015" will return objects with names like
// "advertiser group June 2015", "advertiser group April 2015", or
// simply "advertiser group 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "advertisergroup" will match objects
// with name "my advertisergroup", "advertisergroup 2015", or simply
// "advertisergroup".
func (c *AdvertiserGroupsListCall) SearchString(searchString string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *AdvertiserGroupsListCall) SortField(sortField string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *AdvertiserGroupsListCall) SortOrder(sortOrder string) *AdvertiserGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsListCall) Fields(s ...googleapi.Field) *AdvertiserGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdvertiserGroupsListCall) IfNoneMatch(entityTag string) *AdvertiserGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsListCall) Context(ctx context.Context) *AdvertiserGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.list" call.
// Exactly one of *AdvertiserGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *AdvertiserGroupsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsListCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertiser groups, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertiserGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only advertiser groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"advertiser*2015\" will return objects with names like \"advertiser group June 2015\", \"advertiser group April 2015\", or simply \"advertiser group 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"advertisergroup\" will match objects with name \"my advertisergroup\", \"advertisergroup 2015\", or simply \"advertisergroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "response": {
	//     "$ref": "AdvertiserGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AdvertiserGroupsListCall) Pages(ctx context.Context, f func(*AdvertiserGroupsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.advertiserGroups.patch":

type AdvertiserGroupsPatchCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Patch: Updates an existing advertiser group. This method supports
// patch semantics.
func (r *AdvertiserGroupsService) Patch(profileId int64, id int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsPatchCall {
	c := &AdvertiserGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.advertisergroup = advertisergroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsPatchCall) Fields(s ...googleapi.Field) *AdvertiserGroupsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsPatchCall) Context(ctx context.Context) *AdvertiserGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertisergroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.patch" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsPatchCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing advertiser group. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.advertiserGroups.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser group ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertiserGroups.update":

type AdvertiserGroupsUpdateCall struct {
	s               *Service
	profileId       int64
	advertisergroup *AdvertiserGroup
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Update: Updates an existing advertiser group.
func (r *AdvertiserGroupsService) Update(profileId int64, advertisergroup *AdvertiserGroup) *AdvertiserGroupsUpdateCall {
	c := &AdvertiserGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertisergroup = advertisergroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertiserGroupsUpdateCall) Fields(s ...googleapi.Field) *AdvertiserGroupsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertiserGroupsUpdateCall) Context(ctx context.Context) *AdvertiserGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertiserGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertisergroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertiserGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertiserGroups.update" call.
// Exactly one of *AdvertiserGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *AdvertiserGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertiserGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*AdvertiserGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertiserGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing advertiser group.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.advertiserGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertiserGroups",
	//   "request": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "response": {
	//     "$ref": "AdvertiserGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.get":

type AdvertisersGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one advertiser by ID.
func (r *AdvertisersService) Get(profileId int64, id int64) *AdvertisersGetCall {
	c := &AdvertisersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertisersGetCall) Fields(s ...googleapi.Field) *AdvertisersGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdvertisersGetCall) IfNoneMatch(entityTag string) *AdvertisersGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertisersGetCall) Context(ctx context.Context) *AdvertisersGetCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertisersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertisers/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.get" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertisersGetCall) Do(opts ...googleapi.CallOption) (*Advertiser, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Advertiser{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one advertiser by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertisers.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers/{id}",
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.insert":

type AdvertisersInsertCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new advertiser.
func (r *AdvertisersService) Insert(profileId int64, advertiser *Advertiser) *AdvertisersInsertCall {
	c := &AdvertisersInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertiser = advertiser
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertisersInsertCall) Fields(s ...googleapi.Field) *AdvertisersInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertisersInsertCall) Context(ctx context.Context) *AdvertisersInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertisersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertiser)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.insert" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertisersInsertCall) Do(opts ...googleapi.CallOption) (*Advertiser, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Advertiser{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new advertiser.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.advertisers.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.list":

type AdvertisersListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of advertisers, possibly filtered.
func (r *AdvertisersService) List(profileId int64) *AdvertisersListCall {
	c := &AdvertisersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserGroupIds sets the optional parameter "advertiserGroupIds":
// Select only advertisers with these advertiser group IDs.
func (c *AdvertisersListCall) AdvertiserGroupIds(advertiserGroupIds ...int64) *AdvertisersListCall {
	var advertiserGroupIds_ []string
	for _, v := range advertiserGroupIds {
		advertiserGroupIds_ = append(advertiserGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserGroupIds", advertiserGroupIds_)
	return c
}

// FloodlightConfigurationIds sets the optional parameter
// "floodlightConfigurationIds": Select only advertisers with these
// floodlight configuration IDs.
func (c *AdvertisersListCall) FloodlightConfigurationIds(floodlightConfigurationIds ...int64) *AdvertisersListCall {
	var floodlightConfigurationIds_ []string
	for _, v := range floodlightConfigurationIds {
		floodlightConfigurationIds_ = append(floodlightConfigurationIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("floodlightConfigurationIds", floodlightConfigurationIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only advertisers with
// these IDs.
func (c *AdvertisersListCall) Ids(ids ...int64) *AdvertisersListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// IncludeAdvertisersWithoutGroupsOnly sets the optional parameter
// "includeAdvertisersWithoutGroupsOnly": Select only advertisers which
// do not belong to any advertiser group.
func (c *AdvertisersListCall) IncludeAdvertisersWithoutGroupsOnly(includeAdvertisersWithoutGroupsOnly bool) *AdvertisersListCall {
	c.urlParams_.Set("includeAdvertisersWithoutGroupsOnly", fmt.Sprint(includeAdvertisersWithoutGroupsOnly))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *AdvertisersListCall) MaxResults(maxResults int64) *AdvertisersListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OnlyParent sets the optional parameter "onlyParent": Select only
// advertisers which use another advertiser's floodlight configuration.
func (c *AdvertisersListCall) OnlyParent(onlyParent bool) *AdvertisersListCall {
	c.urlParams_.Set("onlyParent", fmt.Sprint(onlyParent))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *AdvertisersListCall) PageToken(pageToken string) *AdvertisersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "advertiser*2015" will return objects with names like
// "advertiser June 2015", "advertiser April 2015", or simply
// "advertiser 2015". Most of the searches also add wildcards implicitly
// at the start and the end of the search string. For example, a search
// string of "advertiser" will match objects with name "my advertiser",
// "advertiser 2015", or simply "advertiser".
func (c *AdvertisersListCall) SearchString(searchString string) *AdvertisersListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *AdvertisersListCall) SortField(sortField string) *AdvertisersListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *AdvertisersListCall) SortOrder(sortOrder string) *AdvertisersListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Status sets the optional parameter "status": Select only advertisers
// with the specified status.
//
// Possible values:
//   "APPROVED"
//   "ON_HOLD"
func (c *AdvertisersListCall) Status(status string) *AdvertisersListCall {
	c.urlParams_.Set("status", status)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// advertisers with these subaccount IDs.
func (c *AdvertisersListCall) SubaccountId(subaccountId int64) *AdvertisersListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertisersListCall) Fields(s ...googleapi.Field) *AdvertisersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *AdvertisersListCall) IfNoneMatch(entityTag string) *AdvertisersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertisersListCall) Context(ctx context.Context) *AdvertisersListCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertisersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.list" call.
// Exactly one of *AdvertisersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *AdvertisersListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *AdvertisersListCall) Do(opts ...googleapi.CallOption) (*AdvertisersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &AdvertisersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertisers, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.advertisers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserGroupIds": {
	//       "description": "Select only advertisers with these advertiser group IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "floodlightConfigurationIds": {
	//       "description": "Select only advertisers with these floodlight configuration IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only advertisers with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "includeAdvertisersWithoutGroupsOnly": {
	//       "description": "Select only advertisers which do not belong to any advertiser group.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "onlyParent": {
	//       "description": "Select only advertisers which use another advertiser's floodlight configuration.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"advertiser*2015\" will return objects with names like \"advertiser June 2015\", \"advertiser April 2015\", or simply \"advertiser 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"advertiser\" will match objects with name \"my advertiser\", \"advertiser 2015\", or simply \"advertiser\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "status": {
	//       "description": "Select only advertisers with the specified status.",
	//       "enum": [
	//         "APPROVED",
	//         "ON_HOLD"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only advertisers with these subaccount IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "response": {
	//     "$ref": "AdvertisersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *AdvertisersListCall) Pages(ctx context.Context, f func(*AdvertisersListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.advertisers.patch":

type AdvertisersPatchCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing advertiser. This method supports patch
// semantics.
func (r *AdvertisersService) Patch(profileId int64, id int64, advertiser *Advertiser) *AdvertisersPatchCall {
	c := &AdvertisersPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.advertiser = advertiser
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertisersPatchCall) Fields(s ...googleapi.Field) *AdvertisersPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertisersPatchCall) Context(ctx context.Context) *AdvertisersPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertisersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertiser)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.patch" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertisersPatchCall) Do(opts ...googleapi.CallOption) (*Advertiser, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Advertiser{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing advertiser. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.advertisers.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.advertisers.update":

type AdvertisersUpdateCall struct {
	s          *Service
	profileId  int64
	advertiser *Advertiser
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing advertiser.
func (r *AdvertisersService) Update(profileId int64, advertiser *Advertiser) *AdvertisersUpdateCall {
	c := &AdvertisersUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertiser = advertiser
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *AdvertisersUpdateCall) Fields(s ...googleapi.Field) *AdvertisersUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *AdvertisersUpdateCall) Context(ctx context.Context) *AdvertisersUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *AdvertisersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.advertiser)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/advertisers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.advertisers.update" call.
// Exactly one of *Advertiser or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Advertiser.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *AdvertisersUpdateCall) Do(opts ...googleapi.CallOption) (*Advertiser, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Advertiser{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing advertiser.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.advertisers.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/advertisers",
	//   "request": {
	//     "$ref": "Advertiser"
	//   },
	//   "response": {
	//     "$ref": "Advertiser"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.browsers.list":

type BrowsersListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of browsers.
func (r *BrowsersService) List(profileId int64) *BrowsersListCall {
	c := &BrowsersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *BrowsersListCall) Fields(s ...googleapi.Field) *BrowsersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *BrowsersListCall) IfNoneMatch(entityTag string) *BrowsersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *BrowsersListCall) Context(ctx context.Context) *BrowsersListCall {
	c.ctx_ = ctx
	return c
}

func (c *BrowsersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/browsers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.browsers.list" call.
// Exactly one of *BrowsersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *BrowsersListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *BrowsersListCall) Do(opts ...googleapi.CallOption) (*BrowsersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &BrowsersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of browsers.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.browsers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/browsers",
	//   "response": {
	//     "$ref": "BrowsersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaignCreativeAssociations.insert":

type CampaignCreativeAssociationsInsertCall struct {
	s                           *Service
	profileId                   int64
	campaignId                  int64
	campaigncreativeassociation *CampaignCreativeAssociation
	urlParams_                  gensupport.URLParams
	ctx_                        context.Context
}

// Insert: Associates a creative with the specified campaign. This
// method creates a default ad with dimensions matching the creative in
// the campaign if such a default ad does not exist already.
func (r *CampaignCreativeAssociationsService) Insert(profileId int64, campaignId int64, campaigncreativeassociation *CampaignCreativeAssociation) *CampaignCreativeAssociationsInsertCall {
	c := &CampaignCreativeAssociationsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.campaigncreativeassociation = campaigncreativeassociation
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignCreativeAssociationsInsertCall) Fields(s ...googleapi.Field) *CampaignCreativeAssociationsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignCreativeAssociationsInsertCall) Context(ctx context.Context) *CampaignCreativeAssociationsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignCreativeAssociationsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.campaigncreativeassociation)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaignCreativeAssociations.insert" call.
// Exactly one of *CampaignCreativeAssociation or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CampaignCreativeAssociation.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CampaignCreativeAssociationsInsertCall) Do(opts ...googleapi.CallOption) (*CampaignCreativeAssociation, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignCreativeAssociation{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Associates a creative with the specified campaign. This method creates a default ad with dimensions matching the creative in the campaign if such a default ad does not exist already.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.campaignCreativeAssociations.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Campaign ID in this association.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "request": {
	//     "$ref": "CampaignCreativeAssociation"
	//   },
	//   "response": {
	//     "$ref": "CampaignCreativeAssociation"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaignCreativeAssociations.list":

type CampaignCreativeAssociationsListCall struct {
	s            *Service
	profileId    int64
	campaignId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves the list of creative IDs associated with the
// specified campaign.
func (r *CampaignCreativeAssociationsService) List(profileId int64, campaignId int64) *CampaignCreativeAssociationsListCall {
	c := &CampaignCreativeAssociationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CampaignCreativeAssociationsListCall) MaxResults(maxResults int64) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CampaignCreativeAssociationsListCall) PageToken(pageToken string) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CampaignCreativeAssociationsListCall) SortOrder(sortOrder string) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignCreativeAssociationsListCall) Fields(s ...googleapi.Field) *CampaignCreativeAssociationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CampaignCreativeAssociationsListCall) IfNoneMatch(entityTag string) *CampaignCreativeAssociationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignCreativeAssociationsListCall) Context(ctx context.Context) *CampaignCreativeAssociationsListCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignCreativeAssociationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaignCreativeAssociations.list" call.
// Exactly one of *CampaignCreativeAssociationsListResponse or error
// will be non-nil. Any non-2xx status code is an error. Response
// headers are in either
// *CampaignCreativeAssociationsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *CampaignCreativeAssociationsListCall) Do(opts ...googleapi.CallOption) (*CampaignCreativeAssociationsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignCreativeAssociationsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of creative IDs associated with the specified campaign.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaignCreativeAssociations.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Campaign ID in this association.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/campaignCreativeAssociations",
	//   "response": {
	//     "$ref": "CampaignCreativeAssociationsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CampaignCreativeAssociationsListCall) Pages(ctx context.Context, f func(*CampaignCreativeAssociationsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.campaigns.get":

type CampaignsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one campaign by ID.
func (r *CampaignsService) Get(profileId int64, id int64) *CampaignsGetCall {
	c := &CampaignsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsGetCall) Fields(s ...googleapi.Field) *CampaignsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CampaignsGetCall) IfNoneMatch(entityTag string) *CampaignsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignsGetCall) Context(ctx context.Context) *CampaignsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.get" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CampaignsGetCall) Do(opts ...googleapi.CallOption) (*Campaign, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Campaign{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one campaign by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaigns.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{id}",
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.insert":

type CampaignsInsertCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new campaign.
func (r *CampaignsService) Insert(profileId int64, defaultLandingPageName string, defaultLandingPageUrl string, campaign *Campaign) *CampaignsInsertCall {
	c := &CampaignsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("defaultLandingPageName", defaultLandingPageName)
	c.urlParams_.Set("defaultLandingPageUrl", defaultLandingPageUrl)
	c.campaign = campaign
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsInsertCall) Fields(s ...googleapi.Field) *CampaignsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignsInsertCall) Context(ctx context.Context) *CampaignsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.campaign)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.insert" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CampaignsInsertCall) Do(opts ...googleapi.CallOption) (*Campaign, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Campaign{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new campaign.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.campaigns.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "defaultLandingPageName",
	//     "defaultLandingPageUrl"
	//   ],
	//   "parameters": {
	//     "defaultLandingPageName": {
	//       "description": "Default landing page name for this new campaign. Must be less than 256 characters long.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "defaultLandingPageUrl": {
	//       "description": "Default landing page URL for this new campaign.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.list":

type CampaignsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of campaigns, possibly filtered.
func (r *CampaignsService) List(profileId int64) *CampaignsListCall {
	c := &CampaignsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserGroupIds sets the optional parameter "advertiserGroupIds":
// Select only campaigns whose advertisers belong to these advertiser
// groups.
func (c *CampaignsListCall) AdvertiserGroupIds(advertiserGroupIds ...int64) *CampaignsListCall {
	var advertiserGroupIds_ []string
	for _, v := range advertiserGroupIds {
		advertiserGroupIds_ = append(advertiserGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserGroupIds", advertiserGroupIds_)
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only campaigns that belong to these advertisers.
func (c *CampaignsListCall) AdvertiserIds(advertiserIds ...int64) *CampaignsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// campaigns. Don't set this field to select both archived and
// non-archived campaigns.
func (c *CampaignsListCall) Archived(archived bool) *CampaignsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// AtLeastOneOptimizationActivity sets the optional parameter
// "atLeastOneOptimizationActivity": Select only campaigns that have at
// least one optimization activity.
func (c *CampaignsListCall) AtLeastOneOptimizationActivity(atLeastOneOptimizationActivity bool) *CampaignsListCall {
	c.urlParams_.Set("atLeastOneOptimizationActivity", fmt.Sprint(atLeastOneOptimizationActivity))
	return c
}

// ExcludedIds sets the optional parameter "excludedIds": Exclude
// campaigns with these IDs.
func (c *CampaignsListCall) ExcludedIds(excludedIds ...int64) *CampaignsListCall {
	var excludedIds_ []string
	for _, v := range excludedIds {
		excludedIds_ = append(excludedIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("excludedIds", excludedIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only campaigns with
// these IDs.
func (c *CampaignsListCall) Ids(ids ...int64) *CampaignsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CampaignsListCall) MaxResults(maxResults int64) *CampaignsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OverriddenEventTagId sets the optional parameter
// "overriddenEventTagId": Select only campaigns that have overridden
// this event tag ID.
func (c *CampaignsListCall) OverriddenEventTagId(overriddenEventTagId int64) *CampaignsListCall {
	c.urlParams_.Set("overriddenEventTagId", fmt.Sprint(overriddenEventTagId))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CampaignsListCall) PageToken(pageToken string) *CampaignsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for campaigns by name or ID. Wildcards (*) are allowed. For
// example, "campaign*2015" will return campaigns with names like
// "campaign June 2015", "campaign April 2015", or simply "campaign
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "campaign" will match campaigns with name "my campaign", "campaign
// 2015", or simply "campaign".
func (c *CampaignsListCall) SearchString(searchString string) *CampaignsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *CampaignsListCall) SortField(sortField string) *CampaignsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CampaignsListCall) SortOrder(sortOrder string) *CampaignsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// campaigns that belong to this subaccount.
func (c *CampaignsListCall) SubaccountId(subaccountId int64) *CampaignsListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsListCall) Fields(s ...googleapi.Field) *CampaignsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CampaignsListCall) IfNoneMatch(entityTag string) *CampaignsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignsListCall) Context(ctx context.Context) *CampaignsListCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.list" call.
// Exactly one of *CampaignsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CampaignsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CampaignsListCall) Do(opts ...googleapi.CallOption) (*CampaignsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CampaignsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of campaigns, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.campaigns.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserGroupIds": {
	//       "description": "Select only campaigns whose advertisers belong to these advertiser groups.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "advertiserIds": {
	//       "description": "Select only campaigns that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived campaigns. Don't set this field to select both archived and non-archived campaigns.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "atLeastOneOptimizationActivity": {
	//       "description": "Select only campaigns that have at least one optimization activity.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "excludedIds": {
	//       "description": "Exclude campaigns with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only campaigns with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "overriddenEventTagId": {
	//       "description": "Select only campaigns that have overridden this event tag ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for campaigns by name or ID. Wildcards (*) are allowed. For example, \"campaign*2015\" will return campaigns with names like \"campaign June 2015\", \"campaign April 2015\", or simply \"campaign 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"campaign\" will match campaigns with name \"my campaign\", \"campaign 2015\", or simply \"campaign\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only campaigns that belong to this subaccount.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "response": {
	//     "$ref": "CampaignsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CampaignsListCall) Pages(ctx context.Context, f func(*CampaignsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.campaigns.patch":

type CampaignsPatchCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing campaign. This method supports patch
// semantics.
func (r *CampaignsService) Patch(profileId int64, id int64, campaign *Campaign) *CampaignsPatchCall {
	c := &CampaignsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.campaign = campaign
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsPatchCall) Fields(s ...googleapi.Field) *CampaignsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignsPatchCall) Context(ctx context.Context) *CampaignsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.campaign)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.patch" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CampaignsPatchCall) Do(opts ...googleapi.CallOption) (*Campaign, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Campaign{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing campaign. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.campaigns.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Campaign ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.campaigns.update":

type CampaignsUpdateCall struct {
	s          *Service
	profileId  int64
	campaign   *Campaign
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing campaign.
func (r *CampaignsService) Update(profileId int64, campaign *Campaign) *CampaignsUpdateCall {
	c := &CampaignsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaign = campaign
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CampaignsUpdateCall) Fields(s ...googleapi.Field) *CampaignsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CampaignsUpdateCall) Context(ctx context.Context) *CampaignsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *CampaignsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.campaign)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.campaigns.update" call.
// Exactly one of *Campaign or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Campaign.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CampaignsUpdateCall) Do(opts ...googleapi.CallOption) (*Campaign, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Campaign{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing campaign.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.campaigns.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns",
	//   "request": {
	//     "$ref": "Campaign"
	//   },
	//   "response": {
	//     "$ref": "Campaign"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.changeLogs.get":

type ChangeLogsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one change log by ID.
func (r *ChangeLogsService) Get(profileId int64, id int64) *ChangeLogsGetCall {
	c := &ChangeLogsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ChangeLogsGetCall) Fields(s ...googleapi.Field) *ChangeLogsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ChangeLogsGetCall) IfNoneMatch(entityTag string) *ChangeLogsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ChangeLogsGetCall) Context(ctx context.Context) *ChangeLogsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *ChangeLogsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/changeLogs/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.changeLogs.get" call.
// Exactly one of *ChangeLog or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ChangeLog.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ChangeLogsGetCall) Do(opts ...googleapi.CallOption) (*ChangeLog, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ChangeLog{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one change log by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.changeLogs.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Change log ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/changeLogs/{id}",
	//   "response": {
	//     "$ref": "ChangeLog"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.changeLogs.list":

type ChangeLogsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of change logs.
func (r *ChangeLogsService) List(profileId int64) *ChangeLogsListCall {
	c := &ChangeLogsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Action sets the optional parameter "action": Select only change logs
// with the specified action.
//
// Possible values:
//   "ACTION_ADD"
//   "ACTION_ASSIGN"
//   "ACTION_ASSOCIATE"
//   "ACTION_CREATE"
//   "ACTION_DELETE"
//   "ACTION_DISABLE"
//   "ACTION_EMAIL_TAGS"
//   "ACTION_ENABLE"
//   "ACTION_LINK"
//   "ACTION_MARK_AS_DEFAULT"
//   "ACTION_PUSH"
//   "ACTION_REMOVE"
//   "ACTION_SEND"
//   "ACTION_SHARE"
//   "ACTION_UNASSIGN"
//   "ACTION_UNLINK"
//   "ACTION_UPDATE"
func (c *ChangeLogsListCall) Action(action string) *ChangeLogsListCall {
	c.urlParams_.Set("action", action)
	return c
}

// Ids sets the optional parameter "ids": Select only change logs with
// these IDs.
func (c *ChangeLogsListCall) Ids(ids ...int64) *ChangeLogsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxChangeTime sets the optional parameter "maxChangeTime": Select
// only change logs whose change time is before the specified
// maxChangeTime.The time should be formatted as an RFC3339 date/time
// string. For example, for 10:54 PM on July 18th, 2015, in the
// America/New York time zone, the format is
// "2015-07-18T22:54:00-04:00". In other words, the year, month, day,
// the letter T, the hour (24-hour clock system), minute, second, and
// then the time zone offset.
func (c *ChangeLogsListCall) MaxChangeTime(maxChangeTime string) *ChangeLogsListCall {
	c.urlParams_.Set("maxChangeTime", maxChangeTime)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ChangeLogsListCall) MaxResults(maxResults int64) *ChangeLogsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// MinChangeTime sets the optional parameter "minChangeTime": Select
// only change logs whose change time is before the specified
// minChangeTime.The time should be formatted as an RFC3339 date/time
// string. For example, for 10:54 PM on July 18th, 2015, in the
// America/New York time zone, the format is
// "2015-07-18T22:54:00-04:00". In other words, the year, month, day,
// the letter T, the hour (24-hour clock system), minute, second, and
// then the time zone offset.
func (c *ChangeLogsListCall) MinChangeTime(minChangeTime string) *ChangeLogsListCall {
	c.urlParams_.Set("minChangeTime", minChangeTime)
	return c
}

// ObjectIds sets the optional parameter "objectIds": Select only change
// logs with these object IDs.
func (c *ChangeLogsListCall) ObjectIds(objectIds ...int64) *ChangeLogsListCall {
	var objectIds_ []string
	for _, v := range objectIds {
		objectIds_ = append(objectIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("objectIds", objectIds_)
	return c
}

// ObjectType sets the optional parameter "objectType": Select only
// change logs with the specified object type.
//
// Possible values:
//   "OBJECT_ACCOUNT"
//   "OBJECT_ACCOUNT_BILLING_FEATURE"
//   "OBJECT_AD"
//   "OBJECT_ADVERTISER"
//   "OBJECT_ADVERTISER_GROUP"
//   "OBJECT_BILLING_ACCOUNT_GROUP"
//   "OBJECT_BILLING_FEATURE"
//   "OBJECT_BILLING_MINIMUM_FEE"
//   "OBJECT_BILLING_PROFILE"
//   "OBJECT_CAMPAIGN"
//   "OBJECT_CONTENT_CATEGORY"
//   "OBJECT_CREATIVE"
//   "OBJECT_CREATIVE_ASSET"
//   "OBJECT_CREATIVE_BUNDLE"
//   "OBJECT_CREATIVE_FIELD"
//   "OBJECT_CREATIVE_GROUP"
//   "OBJECT_DFA_SITE"
//   "OBJECT_EVENT_TAG"
//   "OBJECT_FLOODLIGHT_ACTIVITY_GROUP"
//   "OBJECT_FLOODLIGHT_ACTVITY"
//   "OBJECT_FLOODLIGHT_CONFIGURATION"
//   "OBJECT_INSTREAM_CREATIVE"
//   "OBJECT_LANDING_PAGE"
//   "OBJECT_MEDIA_ORDER"
//   "OBJECT_PLACEMENT"
//   "OBJECT_PLACEMENT_STRATEGY"
//   "OBJECT_PLAYSTORE_LINK"
//   "OBJECT_PROVIDED_LIST_CLIENT"
//   "OBJECT_RATE_CARD"
//   "OBJECT_REMARKETING_LIST"
//   "OBJECT_RICHMEDIA_CREATIVE"
//   "OBJECT_SD_SITE"
//   "OBJECT_SIZE"
//   "OBJECT_SUBACCOUNT"
//   "OBJECT_USER_PROFILE"
//   "OBJECT_USER_PROFILE_FILTER"
//   "OBJECT_USER_ROLE"
func (c *ChangeLogsListCall) ObjectType(objectType string) *ChangeLogsListCall {
	c.urlParams_.Set("objectType", objectType)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *ChangeLogsListCall) PageToken(pageToken string) *ChangeLogsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Select only
// change logs whose object ID, user name, old or new values match the
// search string.
func (c *ChangeLogsListCall) SearchString(searchString string) *ChangeLogsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// UserProfileIds sets the optional parameter "userProfileIds": Select
// only change logs with these user profile IDs.
func (c *ChangeLogsListCall) UserProfileIds(userProfileIds ...int64) *ChangeLogsListCall {
	var userProfileIds_ []string
	for _, v := range userProfileIds {
		userProfileIds_ = append(userProfileIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("userProfileIds", userProfileIds_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ChangeLogsListCall) Fields(s ...googleapi.Field) *ChangeLogsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ChangeLogsListCall) IfNoneMatch(entityTag string) *ChangeLogsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ChangeLogsListCall) Context(ctx context.Context) *ChangeLogsListCall {
	c.ctx_ = ctx
	return c
}

func (c *ChangeLogsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/changeLogs")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.changeLogs.list" call.
// Exactly one of *ChangeLogsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ChangeLogsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ChangeLogsListCall) Do(opts ...googleapi.CallOption) (*ChangeLogsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ChangeLogsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of change logs.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.changeLogs.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "action": {
	//       "description": "Select only change logs with the specified action.",
	//       "enum": [
	//         "ACTION_ADD",
	//         "ACTION_ASSIGN",
	//         "ACTION_ASSOCIATE",
	//         "ACTION_CREATE",
	//         "ACTION_DELETE",
	//         "ACTION_DISABLE",
	//         "ACTION_EMAIL_TAGS",
	//         "ACTION_ENABLE",
	//         "ACTION_LINK",
	//         "ACTION_MARK_AS_DEFAULT",
	//         "ACTION_PUSH",
	//         "ACTION_REMOVE",
	//         "ACTION_SEND",
	//         "ACTION_SHARE",
	//         "ACTION_UNASSIGN",
	//         "ACTION_UNLINK",
	//         "ACTION_UPDATE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only change logs with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxChangeTime": {
	//       "description": "Select only change logs whose change time is before the specified maxChangeTime.The time should be formatted as an RFC3339 date/time string. For example, for 10:54 PM on July 18th, 2015, in the America/New York time zone, the format is \"2015-07-18T22:54:00-04:00\". In other words, the year, month, day, the letter T, the hour (24-hour clock system), minute, second, and then the time zone offset.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "minChangeTime": {
	//       "description": "Select only change logs whose change time is before the specified minChangeTime.The time should be formatted as an RFC3339 date/time string. For example, for 10:54 PM on July 18th, 2015, in the America/New York time zone, the format is \"2015-07-18T22:54:00-04:00\". In other words, the year, month, day, the letter T, the hour (24-hour clock system), minute, second, and then the time zone offset.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "objectIds": {
	//       "description": "Select only change logs with these object IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Select only change logs with the specified object type.",
	//       "enum": [
	//         "OBJECT_ACCOUNT",
	//         "OBJECT_ACCOUNT_BILLING_FEATURE",
	//         "OBJECT_AD",
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_ADVERTISER_GROUP",
	//         "OBJECT_BILLING_ACCOUNT_GROUP",
	//         "OBJECT_BILLING_FEATURE",
	//         "OBJECT_BILLING_MINIMUM_FEE",
	//         "OBJECT_BILLING_PROFILE",
	//         "OBJECT_CAMPAIGN",
	//         "OBJECT_CONTENT_CATEGORY",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_CREATIVE_ASSET",
	//         "OBJECT_CREATIVE_BUNDLE",
	//         "OBJECT_CREATIVE_FIELD",
	//         "OBJECT_CREATIVE_GROUP",
	//         "OBJECT_DFA_SITE",
	//         "OBJECT_EVENT_TAG",
	//         "OBJECT_FLOODLIGHT_ACTIVITY_GROUP",
	//         "OBJECT_FLOODLIGHT_ACTVITY",
	//         "OBJECT_FLOODLIGHT_CONFIGURATION",
	//         "OBJECT_INSTREAM_CREATIVE",
	//         "OBJECT_LANDING_PAGE",
	//         "OBJECT_MEDIA_ORDER",
	//         "OBJECT_PLACEMENT",
	//         "OBJECT_PLACEMENT_STRATEGY",
	//         "OBJECT_PLAYSTORE_LINK",
	//         "OBJECT_PROVIDED_LIST_CLIENT",
	//         "OBJECT_RATE_CARD",
	//         "OBJECT_REMARKETING_LIST",
	//         "OBJECT_RICHMEDIA_CREATIVE",
	//         "OBJECT_SD_SITE",
	//         "OBJECT_SIZE",
	//         "OBJECT_SUBACCOUNT",
	//         "OBJECT_USER_PROFILE",
	//         "OBJECT_USER_PROFILE_FILTER",
	//         "OBJECT_USER_ROLE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Select only change logs whose object ID, user name, old or new values match the search string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "userProfileIds": {
	//       "description": "Select only change logs with these user profile IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/changeLogs",
	//   "response": {
	//     "$ref": "ChangeLogsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ChangeLogsListCall) Pages(ctx context.Context, f func(*ChangeLogsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.cities.list":

type CitiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of cities, possibly filtered.
func (r *CitiesService) List(profileId int64) *CitiesListCall {
	c := &CitiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// CountryDartIds sets the optional parameter "countryDartIds": Select
// only cities from these countries.
func (c *CitiesListCall) CountryDartIds(countryDartIds ...int64) *CitiesListCall {
	var countryDartIds_ []string
	for _, v := range countryDartIds {
		countryDartIds_ = append(countryDartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("countryDartIds", countryDartIds_)
	return c
}

// DartIds sets the optional parameter "dartIds": Select only cities
// with these DART IDs.
func (c *CitiesListCall) DartIds(dartIds ...int64) *CitiesListCall {
	var dartIds_ []string
	for _, v := range dartIds {
		dartIds_ = append(dartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("dartIds", dartIds_)
	return c
}

// NamePrefix sets the optional parameter "namePrefix": Select only
// cities with names starting with this prefix.
func (c *CitiesListCall) NamePrefix(namePrefix string) *CitiesListCall {
	c.urlParams_.Set("namePrefix", namePrefix)
	return c
}

// RegionDartIds sets the optional parameter "regionDartIds": Select
// only cities from these regions.
func (c *CitiesListCall) RegionDartIds(regionDartIds ...int64) *CitiesListCall {
	var regionDartIds_ []string
	for _, v := range regionDartIds {
		regionDartIds_ = append(regionDartIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("regionDartIds", regionDartIds_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CitiesListCall) Fields(s ...googleapi.Field) *CitiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CitiesListCall) IfNoneMatch(entityTag string) *CitiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CitiesListCall) Context(ctx context.Context) *CitiesListCall {
	c.ctx_ = ctx
	return c
}

func (c *CitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/cities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.cities.list" call.
// Exactly one of *CitiesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CitiesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CitiesListCall) Do(opts ...googleapi.CallOption) (*CitiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CitiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of cities, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.cities.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "countryDartIds": {
	//       "description": "Select only cities from these countries.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "dartIds": {
	//       "description": "Select only cities with these DART IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "namePrefix": {
	//       "description": "Select only cities with names starting with this prefix.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "regionDartIds": {
	//       "description": "Select only cities from these regions.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/cities",
	//   "response": {
	//     "$ref": "CitiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.connectionTypes.list":

type ConnectionTypesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of connection types.
func (r *ConnectionTypesService) List(profileId int64) *ConnectionTypesListCall {
	c := &ConnectionTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ConnectionTypesListCall) Fields(s ...googleapi.Field) *ConnectionTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ConnectionTypesListCall) IfNoneMatch(entityTag string) *ConnectionTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ConnectionTypesListCall) Context(ctx context.Context) *ConnectionTypesListCall {
	c.ctx_ = ctx
	return c
}

func (c *ConnectionTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/connectionTypes")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.connectionTypes.list" call.
// Exactly one of *ConnectionTypesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *ConnectionTypesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ConnectionTypesListCall) Do(opts ...googleapi.CallOption) (*ConnectionTypesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ConnectionTypesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of connection types.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.connectionTypes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/connectionTypes",
	//   "response": {
	//     "$ref": "ConnectionTypesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.delete":

type ContentCategoriesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing content category.
func (r *ContentCategoriesService) Delete(profileId int64, id int64) *ContentCategoriesDeleteCall {
	c := &ContentCategoriesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesDeleteCall) Fields(s ...googleapi.Field) *ContentCategoriesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesDeleteCall) Context(ctx context.Context) *ContentCategoriesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.delete" call.
func (c *ContentCategoriesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing content category.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.contentCategories.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Content category ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.get":

type ContentCategoriesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one content category by ID.
func (r *ContentCategoriesService) Get(profileId int64, id int64) *ContentCategoriesGetCall {
	c := &ContentCategoriesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesGetCall) Fields(s ...googleapi.Field) *ContentCategoriesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ContentCategoriesGetCall) IfNoneMatch(entityTag string) *ContentCategoriesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesGetCall) Context(ctx context.Context) *ContentCategoriesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.get" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesGetCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one content category by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.contentCategories.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Content category ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories/{id}",
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.insert":

type ContentCategoriesInsertCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Insert: Inserts a new content category.
func (r *ContentCategoriesService) Insert(profileId int64, contentcategory *ContentCategory) *ContentCategoriesInsertCall {
	c := &ContentCategoriesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.contentcategory = contentcategory
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesInsertCall) Fields(s ...googleapi.Field) *ContentCategoriesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesInsertCall) Context(ctx context.Context) *ContentCategoriesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.contentcategory)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.insert" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesInsertCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new content category.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.contentCategories.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.list":

type ContentCategoriesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of content categories, possibly filtered.
func (r *ContentCategoriesService) List(profileId int64) *ContentCategoriesListCall {
	c := &ContentCategoriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only content categories
// with these IDs.
func (c *ContentCategoriesListCall) Ids(ids ...int64) *ContentCategoriesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ContentCategoriesListCall) MaxResults(maxResults int64) *ContentCategoriesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *ContentCategoriesListCall) PageToken(pageToken string) *ContentCategoriesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "contentcategory*2015" will return objects with names like
// "contentcategory June 2015", "contentcategory April 2015", or simply
// "contentcategory 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "contentcategory" will match objects with
// name "my contentcategory", "contentcategory 2015", or simply
// "contentcategory".
func (c *ContentCategoriesListCall) SearchString(searchString string) *ContentCategoriesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *ContentCategoriesListCall) SortField(sortField string) *ContentCategoriesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *ContentCategoriesListCall) SortOrder(sortOrder string) *ContentCategoriesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesListCall) Fields(s ...googleapi.Field) *ContentCategoriesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ContentCategoriesListCall) IfNoneMatch(entityTag string) *ContentCategoriesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesListCall) Context(ctx context.Context) *ContentCategoriesListCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.list" call.
// Exactly one of *ContentCategoriesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ContentCategoriesListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesListCall) Do(opts ...googleapi.CallOption) (*ContentCategoriesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategoriesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of content categories, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.contentCategories.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only content categories with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"contentcategory*2015\" will return objects with names like \"contentcategory June 2015\", \"contentcategory April 2015\", or simply \"contentcategory 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"contentcategory\" will match objects with name \"my contentcategory\", \"contentcategory 2015\", or simply \"contentcategory\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "response": {
	//     "$ref": "ContentCategoriesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ContentCategoriesListCall) Pages(ctx context.Context, f func(*ContentCategoriesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.contentCategories.patch":

type ContentCategoriesPatchCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Patch: Updates an existing content category. This method supports
// patch semantics.
func (r *ContentCategoriesService) Patch(profileId int64, id int64, contentcategory *ContentCategory) *ContentCategoriesPatchCall {
	c := &ContentCategoriesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.contentcategory = contentcategory
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesPatchCall) Fields(s ...googleapi.Field) *ContentCategoriesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesPatchCall) Context(ctx context.Context) *ContentCategoriesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.contentcategory)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.patch" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesPatchCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing content category. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.contentCategories.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Content category ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.contentCategories.update":

type ContentCategoriesUpdateCall struct {
	s               *Service
	profileId       int64
	contentcategory *ContentCategory
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Update: Updates an existing content category.
func (r *ContentCategoriesService) Update(profileId int64, contentcategory *ContentCategory) *ContentCategoriesUpdateCall {
	c := &ContentCategoriesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.contentcategory = contentcategory
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ContentCategoriesUpdateCall) Fields(s ...googleapi.Field) *ContentCategoriesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ContentCategoriesUpdateCall) Context(ctx context.Context) *ContentCategoriesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *ContentCategoriesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.contentcategory)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/contentCategories")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.contentCategories.update" call.
// Exactly one of *ContentCategory or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ContentCategory.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ContentCategoriesUpdateCall) Do(opts ...googleapi.CallOption) (*ContentCategory, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ContentCategory{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing content category.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.contentCategories.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/contentCategories",
	//   "request": {
	//     "$ref": "ContentCategory"
	//   },
	//   "response": {
	//     "$ref": "ContentCategory"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.countries.get":

type CountriesGetCall struct {
	s            *Service
	profileId    int64
	dartId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one country by ID.
func (r *CountriesService) Get(profileId int64, dartId int64) *CountriesGetCall {
	c := &CountriesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dartId = dartId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CountriesGetCall) Fields(s ...googleapi.Field) *CountriesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CountriesGetCall) IfNoneMatch(entityTag string) *CountriesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CountriesGetCall) Context(ctx context.Context) *CountriesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CountriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/countries/{dartId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"dartId":    strconv.FormatInt(c.dartId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.countries.get" call.
// Exactly one of *Country or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Country.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *CountriesGetCall) Do(opts ...googleapi.CallOption) (*Country, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Country{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one country by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.countries.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "dartId"
	//   ],
	//   "parameters": {
	//     "dartId": {
	//       "description": "Country DART ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/countries/{dartId}",
	//   "response": {
	//     "$ref": "Country"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.countries.list":

type CountriesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of countries.
func (r *CountriesService) List(profileId int64) *CountriesListCall {
	c := &CountriesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CountriesListCall) Fields(s ...googleapi.Field) *CountriesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CountriesListCall) IfNoneMatch(entityTag string) *CountriesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CountriesListCall) Context(ctx context.Context) *CountriesListCall {
	c.ctx_ = ctx
	return c
}

func (c *CountriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/countries")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.countries.list" call.
// Exactly one of *CountriesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CountriesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CountriesListCall) Do(opts ...googleapi.CallOption) (*CountriesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CountriesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of countries.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.countries.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/countries",
	//   "response": {
	//     "$ref": "CountriesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeAssets.insert":

type CreativeAssetsInsertCall struct {
	s                     *Service
	profileId             int64
	advertiserId          int64
	creativeassetmetadata *CreativeAssetMetadata
	urlParams_            gensupport.URLParams
	media_                io.Reader
	mediaBuffer_          *gensupport.MediaBuffer
	mediaType_            string
	mediaSize_            int64 // mediaSize, if known.  Used only for calls to progressUpdater_.
	progressUpdater_      googleapi.ProgressUpdater
	ctx_                  context.Context
}

// Insert: Inserts a new creative asset.
func (r *CreativeAssetsService) Insert(profileId int64, advertiserId int64, creativeassetmetadata *CreativeAssetMetadata) *CreativeAssetsInsertCall {
	c := &CreativeAssetsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.advertiserId = advertiserId
	c.creativeassetmetadata = creativeassetmetadata
	return c
}

// Media specifies the media to upload in one or more chunks. The chunk
// size may be controlled by supplying a MediaOption generated by
// googleapi.ChunkSize. The chunk size defaults to
// googleapi.DefaultUploadChunkSize.The Content-Type header used in the
// upload request will be determined by sniffing the contents of r,
// unless a MediaOption generated by googleapi.ContentType is
// supplied.
// At most one of Media and ResumableMedia may be set.
func (c *CreativeAssetsInsertCall) Media(r io.Reader, options ...googleapi.MediaOption) *CreativeAssetsInsertCall {
	opts := googleapi.ProcessMediaOptions(options)
	chunkSize := opts.ChunkSize
	if !opts.ForceEmptyContentType {
		r, c.mediaType_ = gensupport.DetermineContentType(r, opts.ContentType)
	}
	c.media_, c.mediaBuffer_ = gensupport.PrepareUpload(r, chunkSize)
	return c
}

// ResumableMedia specifies the media to upload in chunks and can be
// canceled with ctx.
//
// Deprecated: use Media instead.
//
// At most one of Media and ResumableMedia may be set. mediaType
// identifies the MIME media type of the upload, such as "image/png". If
// mediaType is "", it will be auto-detected. The provided ctx will
// supersede any context previously provided to the Context method.
func (c *CreativeAssetsInsertCall) ResumableMedia(ctx context.Context, r io.ReaderAt, size int64, mediaType string) *CreativeAssetsInsertCall {
	c.ctx_ = ctx
	rdr := gensupport.ReaderAtToReader(r, size)
	rdr, c.mediaType_ = gensupport.DetermineContentType(rdr, mediaType)
	c.mediaBuffer_ = gensupport.NewMediaBuffer(rdr, googleapi.DefaultUploadChunkSize)
	c.media_ = nil
	c.mediaSize_ = size
	return c
}

// ProgressUpdater provides a callback function that will be called
// after every chunk. It should be a low-latency function in order to
// not slow down the upload operation. This should only be called when
// using ResumableMedia (as opposed to Media).
func (c *CreativeAssetsInsertCall) ProgressUpdater(pu googleapi.ProgressUpdater) *CreativeAssetsInsertCall {
	c.progressUpdater_ = pu
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeAssetsInsertCall) Fields(s ...googleapi.Field) *CreativeAssetsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
// This context will supersede any context previously provided to the
// ResumableMedia method.
func (c *CreativeAssetsInsertCall) Context(ctx context.Context) *CreativeAssetsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeAssetsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativeassetmetadata)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets")
	if c.media_ != nil || c.mediaBuffer_ != nil {
		urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1)
		protocol := "multipart"
		if c.mediaBuffer_ != nil {
			protocol = "resumable"
		}
		c.urlParams_.Set("uploadType", protocol)
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	if c.media_ != nil {
		combined, ctype := gensupport.CombineBodyMedia(body, "application/json", c.media_, c.mediaType_)
		defer combined.Close()
		reqHeaders.Set("Content-Type", ctype)
		body = combined
	}
	if c.mediaBuffer_ != nil && c.mediaType_ != "" {
		reqHeaders.Set("X-Upload-Content-Type", c.mediaType_)
	}
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":    strconv.FormatInt(c.profileId, 10),
		"advertiserId": strconv.FormatInt(c.advertiserId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeAssets.insert" call.
// Exactly one of *CreativeAssetMetadata or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeAssetMetadata.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeAssetsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeAssetMetadata, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	if c.mediaBuffer_ != nil {
		loc := res.Header.Get("Location")
		rx := &gensupport.ResumableUpload{
			Client:    c.s.client,
			UserAgent: c.s.userAgent(),
			URI:       loc,
			Media:     c.mediaBuffer_,
			MediaType: c.mediaType_,
			Callback: func(curr int64) {
				if c.progressUpdater_ != nil {
					c.progressUpdater_(curr, c.mediaSize_)
				}
			},
		}
		ctx := c.ctx_
		if ctx == nil {
			ctx = context.TODO()
		}
		res, err = rx.Upload(ctx)
		if err != nil {
			return nil, err
		}
		defer res.Body.Close()
		if err := googleapi.CheckResponse(res); err != nil {
			return nil, err
		}
	}
	ret := &CreativeAssetMetadata{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative asset.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeAssets.insert",
	//   "mediaUpload": {
	//     "accept": [
	//       "*/*"
	//     ],
	//     "maxSize": "1024MB",
	//     "protocols": {
	//       "resumable": {
	//         "multipart": true,
	//         "path": "/resumable/upload/dfareporting/v2.0/userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets"
	//       },
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/dfareporting/v2.0/userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets"
	//       }
	//     }
	//   },
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Advertiser ID of this creative. This is a required field.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets",
	//   "request": {
	//     "$ref": "CreativeAssetMetadata"
	//   },
	//   "response": {
	//     "$ref": "CreativeAssetMetadata"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ],
	//   "supportsMediaUpload": true
	// }

}

// method id "dfareporting.creativeFieldValues.delete":

type CreativeFieldValuesDeleteCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	id              int64
	urlParams_      gensupport.URLParams
	ctx_            context.Context
}

// Delete: Deletes an existing creative field value.
func (r *CreativeFieldValuesService) Delete(profileId int64, creativeFieldId int64, id int64) *CreativeFieldValuesDeleteCall {
	c := &CreativeFieldValuesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesDeleteCall) Fields(s ...googleapi.Field) *CreativeFieldValuesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesDeleteCall) Context(ctx context.Context) *CreativeFieldValuesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
		"id":              strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.delete" call.
func (c *CreativeFieldValuesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing creative field value.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.creativeFieldValues.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Creative Field Value ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.get":

type CreativeFieldValuesGetCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	id              int64
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
}

// Get: Gets one creative field value by ID.
func (r *CreativeFieldValuesService) Get(profileId int64, creativeFieldId int64, id int64) *CreativeFieldValuesGetCall {
	c := &CreativeFieldValuesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesGetCall) Fields(s ...googleapi.Field) *CreativeFieldValuesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeFieldValuesGetCall) IfNoneMatch(entityTag string) *CreativeFieldValuesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesGetCall) Context(ctx context.Context) *CreativeFieldValuesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
		"id":              strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.get" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesGetCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one creative field value by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFieldValues.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Creative Field Value ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues/{id}",
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.insert":

type CreativeFieldValuesInsertCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Insert: Inserts a new creative field value.
func (r *CreativeFieldValuesService) Insert(profileId int64, creativeFieldId int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesInsertCall {
	c := &CreativeFieldValuesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesInsertCall) Fields(s ...googleapi.Field) *CreativeFieldValuesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesInsertCall) Context(ctx context.Context) *CreativeFieldValuesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefieldvalue)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.insert" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesInsertCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative field value.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeFieldValues.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.list":

type CreativeFieldValuesListCall struct {
	s               *Service
	profileId       int64
	creativeFieldId int64
	urlParams_      gensupport.URLParams
	ifNoneMatch_    string
	ctx_            context.Context
}

// List: Retrieves a list of creative field values, possibly filtered.
func (r *CreativeFieldValuesService) List(profileId int64, creativeFieldId int64) *CreativeFieldValuesListCall {
	c := &CreativeFieldValuesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	return c
}

// Ids sets the optional parameter "ids": Select only creative field
// values with these IDs.
func (c *CreativeFieldValuesListCall) Ids(ids ...int64) *CreativeFieldValuesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeFieldValuesListCall) MaxResults(maxResults int64) *CreativeFieldValuesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeFieldValuesListCall) PageToken(pageToken string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative field values by their values. Wildcards (e.g.
// *) are not allowed.
func (c *CreativeFieldValuesListCall) SearchString(searchString string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "VALUE"
func (c *CreativeFieldValuesListCall) SortField(sortField string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CreativeFieldValuesListCall) SortOrder(sortOrder string) *CreativeFieldValuesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesListCall) Fields(s ...googleapi.Field) *CreativeFieldValuesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeFieldValuesListCall) IfNoneMatch(entityTag string) *CreativeFieldValuesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesListCall) Context(ctx context.Context) *CreativeFieldValuesListCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.list" call.
// Exactly one of *CreativeFieldValuesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *CreativeFieldValuesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesListCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValuesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValuesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative field values, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFieldValues.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creative field values with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative field values by their values. Wildcards (e.g. *) are not allowed.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "VALUE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "response": {
	//     "$ref": "CreativeFieldValuesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CreativeFieldValuesListCall) Pages(ctx context.Context, f func(*CreativeFieldValuesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.creativeFieldValues.patch":

type CreativeFieldValuesPatchCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Patch: Updates an existing creative field value. This method supports
// patch semantics.
func (r *CreativeFieldValuesService) Patch(profileId int64, creativeFieldId int64, id int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesPatchCall {
	c := &CreativeFieldValuesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesPatchCall) Fields(s ...googleapi.Field) *CreativeFieldValuesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesPatchCall) Context(ctx context.Context) *CreativeFieldValuesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefieldvalue)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.patch" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesPatchCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative field value. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeFieldValues.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Creative Field Value ID",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFieldValues.update":

type CreativeFieldValuesUpdateCall struct {
	s                  *Service
	profileId          int64
	creativeFieldId    int64
	creativefieldvalue *CreativeFieldValue
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Update: Updates an existing creative field value.
func (r *CreativeFieldValuesService) Update(profileId int64, creativeFieldId int64, creativefieldvalue *CreativeFieldValue) *CreativeFieldValuesUpdateCall {
	c := &CreativeFieldValuesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativeFieldId = creativeFieldId
	c.creativefieldvalue = creativefieldvalue
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldValuesUpdateCall) Fields(s ...googleapi.Field) *CreativeFieldValuesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldValuesUpdateCall) Context(ctx context.Context) *CreativeFieldValuesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldValuesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefieldvalue)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":       strconv.FormatInt(c.profileId, 10),
		"creativeFieldId": strconv.FormatInt(c.creativeFieldId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFieldValues.update" call.
// Exactly one of *CreativeFieldValue or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativeFieldValue.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldValuesUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeFieldValue, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldValue{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative field value.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeFieldValues.update",
	//   "parameterOrder": [
	//     "profileId",
	//     "creativeFieldId"
	//   ],
	//   "parameters": {
	//     "creativeFieldId": {
	//       "description": "Creative field ID for this creative field value.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{creativeFieldId}/creativeFieldValues",
	//   "request": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "response": {
	//     "$ref": "CreativeFieldValue"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.delete":

type CreativeFieldsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing creative field.
func (r *CreativeFieldsService) Delete(profileId int64, id int64) *CreativeFieldsDeleteCall {
	c := &CreativeFieldsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsDeleteCall) Fields(s ...googleapi.Field) *CreativeFieldsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsDeleteCall) Context(ctx context.Context) *CreativeFieldsDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.delete" call.
func (c *CreativeFieldsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing creative field.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.creativeFields.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative Field ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.get":

type CreativeFieldsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one creative field by ID.
func (r *CreativeFieldsService) Get(profileId int64, id int64) *CreativeFieldsGetCall {
	c := &CreativeFieldsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsGetCall) Fields(s ...googleapi.Field) *CreativeFieldsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeFieldsGetCall) IfNoneMatch(entityTag string) *CreativeFieldsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsGetCall) Context(ctx context.Context) *CreativeFieldsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.get" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsGetCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one creative field by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFields.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative Field ID",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields/{id}",
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.insert":

type CreativeFieldsInsertCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Insert: Inserts a new creative field.
func (r *CreativeFieldsService) Insert(profileId int64, creativefield *CreativeField) *CreativeFieldsInsertCall {
	c := &CreativeFieldsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativefield = creativefield
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsInsertCall) Fields(s ...googleapi.Field) *CreativeFieldsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsInsertCall) Context(ctx context.Context) *CreativeFieldsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefield)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.insert" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative field.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeFields.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.list":

type CreativeFieldsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of creative fields, possibly filtered.
func (r *CreativeFieldsService) List(profileId int64) *CreativeFieldsListCall {
	c := &CreativeFieldsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only creative fields that belong to these advertisers.
func (c *CreativeFieldsListCall) AdvertiserIds(advertiserIds ...int64) *CreativeFieldsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only creative fields
// with these IDs.
func (c *CreativeFieldsListCall) Ids(ids ...int64) *CreativeFieldsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeFieldsListCall) MaxResults(maxResults int64) *CreativeFieldsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeFieldsListCall) PageToken(pageToken string) *CreativeFieldsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative fields by name or ID. Wildcards (*) are
// allowed. For example, "creativefield*2015" will return creative
// fields with names like "creativefield June 2015", "creativefield
// April 2015", or simply "creativefield 2015". Most of the searches
// also add wild-cards implicitly at the start and the end of the search
// string. For example, a search string of "creativefield" will match
// creative fields with the name "my creativefield", "creativefield
// 2015", or simply "creativefield".
func (c *CreativeFieldsListCall) SearchString(searchString string) *CreativeFieldsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *CreativeFieldsListCall) SortField(sortField string) *CreativeFieldsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CreativeFieldsListCall) SortOrder(sortOrder string) *CreativeFieldsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsListCall) Fields(s ...googleapi.Field) *CreativeFieldsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeFieldsListCall) IfNoneMatch(entityTag string) *CreativeFieldsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsListCall) Context(ctx context.Context) *CreativeFieldsListCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.list" call.
// Exactly one of *CreativeFieldsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CreativeFieldsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsListCall) Do(opts ...googleapi.CallOption) (*CreativeFieldsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeFieldsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative fields, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeFields.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only creative fields that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creative fields with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative fields by name or ID. Wildcards (*) are allowed. For example, \"creativefield*2015\" will return creative fields with names like \"creativefield June 2015\", \"creativefield April 2015\", or simply \"creativefield 2015\". Most of the searches also add wild-cards implicitly at the start and the end of the search string. For example, a search string of \"creativefield\" will match creative fields with the name \"my creativefield\", \"creativefield 2015\", or simply \"creativefield\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "response": {
	//     "$ref": "CreativeFieldsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CreativeFieldsListCall) Pages(ctx context.Context, f func(*CreativeFieldsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.creativeFields.patch":

type CreativeFieldsPatchCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Patch: Updates an existing creative field. This method supports patch
// semantics.
func (r *CreativeFieldsService) Patch(profileId int64, id int64, creativefield *CreativeField) *CreativeFieldsPatchCall {
	c := &CreativeFieldsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.creativefield = creativefield
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsPatchCall) Fields(s ...googleapi.Field) *CreativeFieldsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsPatchCall) Context(ctx context.Context) *CreativeFieldsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefield)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.patch" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsPatchCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative field. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeFields.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative Field ID",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeFields.update":

type CreativeFieldsUpdateCall struct {
	s             *Service
	profileId     int64
	creativefield *CreativeField
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Update: Updates an existing creative field.
func (r *CreativeFieldsService) Update(profileId int64, creativefield *CreativeField) *CreativeFieldsUpdateCall {
	c := &CreativeFieldsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativefield = creativefield
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeFieldsUpdateCall) Fields(s ...googleapi.Field) *CreativeFieldsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeFieldsUpdateCall) Context(ctx context.Context) *CreativeFieldsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeFieldsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativefield)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeFields")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeFields.update" call.
// Exactly one of *CreativeField or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeField.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeFieldsUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeField, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeField{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative field.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeFields.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeFields",
	//   "request": {
	//     "$ref": "CreativeField"
	//   },
	//   "response": {
	//     "$ref": "CreativeField"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.get":

type CreativeGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one creative group by ID.
func (r *CreativeGroupsService) Get(profileId int64, id int64) *CreativeGroupsGetCall {
	c := &CreativeGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsGetCall) Fields(s ...googleapi.Field) *CreativeGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeGroupsGetCall) IfNoneMatch(entityTag string) *CreativeGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeGroupsGetCall) Context(ctx context.Context) *CreativeGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.get" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsGetCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one creative group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups/{id}",
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.insert":

type CreativeGroupsInsertCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Insert: Inserts a new creative group.
func (r *CreativeGroupsService) Insert(profileId int64, creativegroup *CreativeGroup) *CreativeGroupsInsertCall {
	c := &CreativeGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativegroup = creativegroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsInsertCall) Fields(s ...googleapi.Field) *CreativeGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeGroupsInsertCall) Context(ctx context.Context) *CreativeGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativegroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.insert" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsInsertCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative group.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creativeGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.list":

type CreativeGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of creative groups, possibly filtered.
func (r *CreativeGroupsService) List(profileId int64) *CreativeGroupsListCall {
	c := &CreativeGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only creative groups that belong to these advertisers.
func (c *CreativeGroupsListCall) AdvertiserIds(advertiserIds ...int64) *CreativeGroupsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// GroupNumber sets the optional parameter "groupNumber": Select only
// creative groups that belong to this subgroup.
func (c *CreativeGroupsListCall) GroupNumber(groupNumber int64) *CreativeGroupsListCall {
	c.urlParams_.Set("groupNumber", fmt.Sprint(groupNumber))
	return c
}

// Ids sets the optional parameter "ids": Select only creative groups
// with these IDs.
func (c *CreativeGroupsListCall) Ids(ids ...int64) *CreativeGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativeGroupsListCall) MaxResults(maxResults int64) *CreativeGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativeGroupsListCall) PageToken(pageToken string) *CreativeGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for creative groups by name or ID. Wildcards (*) are
// allowed. For example, "creativegroup*2015" will return creative
// groups with names like "creativegroup June 2015", "creativegroup
// April 2015", or simply "creativegroup 2015". Most of the searches
// also add wild-cards implicitly at the start and the end of the search
// string. For example, a search string of "creativegroup" will match
// creative groups with the name "my creativegroup", "creativegroup
// 2015", or simply "creativegroup".
func (c *CreativeGroupsListCall) SearchString(searchString string) *CreativeGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *CreativeGroupsListCall) SortField(sortField string) *CreativeGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CreativeGroupsListCall) SortOrder(sortOrder string) *CreativeGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsListCall) Fields(s ...googleapi.Field) *CreativeGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativeGroupsListCall) IfNoneMatch(entityTag string) *CreativeGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeGroupsListCall) Context(ctx context.Context) *CreativeGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.list" call.
// Exactly one of *CreativeGroupsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *CreativeGroupsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsListCall) Do(opts ...googleapi.CallOption) (*CreativeGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative groups, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creativeGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only creative groups that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "groupNumber": {
	//       "description": "Select only creative groups that belong to this subgroup.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "ids": {
	//       "description": "Select only creative groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for creative groups by name or ID. Wildcards (*) are allowed. For example, \"creativegroup*2015\" will return creative groups with names like \"creativegroup June 2015\", \"creativegroup April 2015\", or simply \"creativegroup 2015\". Most of the searches also add wild-cards implicitly at the start and the end of the search string. For example, a search string of \"creativegroup\" will match creative groups with the name \"my creativegroup\", \"creativegroup 2015\", or simply \"creativegroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "response": {
	//     "$ref": "CreativeGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CreativeGroupsListCall) Pages(ctx context.Context, f func(*CreativeGroupsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.creativeGroups.patch":

type CreativeGroupsPatchCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Patch: Updates an existing creative group. This method supports patch
// semantics.
func (r *CreativeGroupsService) Patch(profileId int64, id int64, creativegroup *CreativeGroup) *CreativeGroupsPatchCall {
	c := &CreativeGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.creativegroup = creativegroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsPatchCall) Fields(s ...googleapi.Field) *CreativeGroupsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeGroupsPatchCall) Context(ctx context.Context) *CreativeGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativegroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.patch" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsPatchCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative group. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creativeGroups.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative group ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creativeGroups.update":

type CreativeGroupsUpdateCall struct {
	s             *Service
	profileId     int64
	creativegroup *CreativeGroup
	urlParams_    gensupport.URLParams
	ctx_          context.Context
}

// Update: Updates an existing creative group.
func (r *CreativeGroupsService) Update(profileId int64, creativegroup *CreativeGroup) *CreativeGroupsUpdateCall {
	c := &CreativeGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creativegroup = creativegroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativeGroupsUpdateCall) Fields(s ...googleapi.Field) *CreativeGroupsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativeGroupsUpdateCall) Context(ctx context.Context) *CreativeGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativeGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creativegroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creativeGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creativeGroups.update" call.
// Exactly one of *CreativeGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *CreativeGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativeGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*CreativeGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativeGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative group.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creativeGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creativeGroups",
	//   "request": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "response": {
	//     "$ref": "CreativeGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.get":

type CreativesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one creative by ID.
func (r *CreativesService) Get(profileId int64, id int64) *CreativesGetCall {
	c := &CreativesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesGetCall) Fields(s ...googleapi.Field) *CreativesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativesGetCall) IfNoneMatch(entityTag string) *CreativesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativesGetCall) Context(ctx context.Context) *CreativesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creatives/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.get" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CreativesGetCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one creative by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creatives.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives/{id}",
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.insert":

type CreativesInsertCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new creative.
func (r *CreativesService) Insert(profileId int64, creative *Creative) *CreativesInsertCall {
	c := &CreativesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creative = creative
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesInsertCall) Fields(s ...googleapi.Field) *CreativesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativesInsertCall) Context(ctx context.Context) *CreativesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creative)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.insert" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CreativesInsertCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new creative.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.creatives.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.list":

type CreativesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of creatives, possibly filtered.
func (r *CreativesService) List(profileId int64) *CreativesListCall {
	c := &CreativesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Active sets the optional parameter "active": Select only active
// creatives. Leave blank to select active and inactive creatives.
func (c *CreativesListCall) Active(active bool) *CreativesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// creatives with this advertiser ID.
func (c *CreativesListCall) AdvertiserId(advertiserId int64) *CreativesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// creatives. Leave blank to select archived and unarchived creatives.
func (c *CreativesListCall) Archived(archived bool) *CreativesListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignId sets the optional parameter "campaignId": Select only
// creatives with this campaign ID.
func (c *CreativesListCall) CampaignId(campaignId int64) *CreativesListCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// CompanionCreativeIds sets the optional parameter
// "companionCreativeIds": Select only in-stream video creatives with
// these companion IDs.
func (c *CreativesListCall) CompanionCreativeIds(companionCreativeIds ...int64) *CreativesListCall {
	var companionCreativeIds_ []string
	for _, v := range companionCreativeIds {
		companionCreativeIds_ = append(companionCreativeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("companionCreativeIds", companionCreativeIds_)
	return c
}

// CreativeFieldIds sets the optional parameter "creativeFieldIds":
// Select only creatives with these creative field IDs.
func (c *CreativesListCall) CreativeFieldIds(creativeFieldIds ...int64) *CreativesListCall {
	var creativeFieldIds_ []string
	for _, v := range creativeFieldIds {
		creativeFieldIds_ = append(creativeFieldIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("creativeFieldIds", creativeFieldIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only creatives with
// these IDs.
func (c *CreativesListCall) Ids(ids ...int64) *CreativesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *CreativesListCall) MaxResults(maxResults int64) *CreativesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *CreativesListCall) PageToken(pageToken string) *CreativesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// RenderingIds sets the optional parameter "renderingIds": Select only
// creatives with these rendering IDs.
func (c *CreativesListCall) RenderingIds(renderingIds ...int64) *CreativesListCall {
	var renderingIds_ []string
	for _, v := range renderingIds {
		renderingIds_ = append(renderingIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("renderingIds", renderingIds_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "creative*2015" will return objects with names like
// "creative June 2015", "creative April 2015", or simply "creative
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "creative" will match objects with name "my creative", "creative
// 2015", or simply "creative".
func (c *CreativesListCall) SearchString(searchString string) *CreativesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only creatives
// with these size IDs.
func (c *CreativesListCall) SizeIds(sizeIds ...int64) *CreativesListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *CreativesListCall) SortField(sortField string) *CreativesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *CreativesListCall) SortOrder(sortOrder string) *CreativesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// StudioCreativeId sets the optional parameter "studioCreativeId":
// Select only creatives corresponding to this Studio creative ID.
func (c *CreativesListCall) StudioCreativeId(studioCreativeId int64) *CreativesListCall {
	c.urlParams_.Set("studioCreativeId", fmt.Sprint(studioCreativeId))
	return c
}

// Types sets the optional parameter "types": Select only creatives with
// these creative types.
//
// Possible values:
//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
//   "CUSTOM_INPAGE"
//   "CUSTOM_INTERSTITIAL"
//   "ENHANCED_BANNER"
//   "ENHANCED_IMAGE"
//   "FLASH_INPAGE"
//   "HTML5_BANNER"
//   "IMAGE"
//   "INSTREAM_VIDEO"
//   "INTERNAL_REDIRECT"
//   "INTERSTITIAL_INTERNAL_REDIRECT"
//   "REDIRECT"
//   "RICH_MEDIA_EXPANDING"
//   "RICH_MEDIA_IM_EXPAND"
//   "RICH_MEDIA_INPAGE"
//   "RICH_MEDIA_INPAGE_FLOATING"
//   "RICH_MEDIA_INTERSTITIAL_FLOAT"
//   "RICH_MEDIA_MOBILE_IN_APP"
//   "RICH_MEDIA_MULTI_FLOATING"
//   "RICH_MEDIA_PEEL_DOWN"
//   "TRACKING_TEXT"
//   "VAST_REDIRECT"
//   "VPAID_LINEAR"
//   "VPAID_NON_LINEAR"
func (c *CreativesListCall) Types(types ...string) *CreativesListCall {
	c.urlParams_.SetMulti("types", append([]string{}, types...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesListCall) Fields(s ...googleapi.Field) *CreativesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *CreativesListCall) IfNoneMatch(entityTag string) *CreativesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativesListCall) Context(ctx context.Context) *CreativesListCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.list" call.
// Exactly one of *CreativesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CreativesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *CreativesListCall) Do(opts ...googleapi.CallOption) (*CreativesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CreativesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creatives, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.creatives.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active creatives. Leave blank to select active and inactive creatives.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only creatives with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived creatives. Leave blank to select archived and unarchived creatives.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignId": {
	//       "description": "Select only creatives with this campaign ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "companionCreativeIds": {
	//       "description": "Select only in-stream video creatives with these companion IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "creativeFieldIds": {
	//       "description": "Select only creatives with these creative field IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only creatives with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "renderingIds": {
	//       "description": "Select only creatives with these rendering IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"creative*2015\" will return objects with names like \"creative June 2015\", \"creative April 2015\", or simply \"creative 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"creative\" will match objects with name \"my creative\", \"creative 2015\", or simply \"creative\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only creatives with these size IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "studioCreativeId": {
	//       "description": "Select only creatives corresponding to this Studio creative ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "types": {
	//       "description": "Select only creatives with these creative types.",
	//       "enum": [
	//         "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO",
	//         "CUSTOM_INPAGE",
	//         "CUSTOM_INTERSTITIAL",
	//         "ENHANCED_BANNER",
	//         "ENHANCED_IMAGE",
	//         "FLASH_INPAGE",
	//         "HTML5_BANNER",
	//         "IMAGE",
	//         "INSTREAM_VIDEO",
	//         "INTERNAL_REDIRECT",
	//         "INTERSTITIAL_INTERNAL_REDIRECT",
	//         "REDIRECT",
	//         "RICH_MEDIA_EXPANDING",
	//         "RICH_MEDIA_IM_EXPAND",
	//         "RICH_MEDIA_INPAGE",
	//         "RICH_MEDIA_INPAGE_FLOATING",
	//         "RICH_MEDIA_INTERSTITIAL_FLOAT",
	//         "RICH_MEDIA_MOBILE_IN_APP",
	//         "RICH_MEDIA_MULTI_FLOATING",
	//         "RICH_MEDIA_PEEL_DOWN",
	//         "TRACKING_TEXT",
	//         "VAST_REDIRECT",
	//         "VPAID_LINEAR",
	//         "VPAID_NON_LINEAR"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "response": {
	//     "$ref": "CreativesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *CreativesListCall) Pages(ctx context.Context, f func(*CreativesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.creatives.patch":

type CreativesPatchCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing creative. This method supports patch
// semantics.
func (r *CreativesService) Patch(profileId int64, id int64, creative *Creative) *CreativesPatchCall {
	c := &CreativesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.creative = creative
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesPatchCall) Fields(s ...googleapi.Field) *CreativesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativesPatchCall) Context(ctx context.Context) *CreativesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creative)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.patch" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CreativesPatchCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.creatives.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Creative ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.creatives.update":

type CreativesUpdateCall struct {
	s          *Service
	profileId  int64
	creative   *Creative
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing creative.
func (r *CreativesService) Update(profileId int64, creative *Creative) *CreativesUpdateCall {
	c := &CreativesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.creative = creative
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *CreativesUpdateCall) Fields(s ...googleapi.Field) *CreativesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *CreativesUpdateCall) Context(ctx context.Context) *CreativesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *CreativesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.creative)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/creatives")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.creatives.update" call.
// Exactly one of *Creative or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Creative.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *CreativesUpdateCall) Do(opts ...googleapi.CallOption) (*Creative, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Creative{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing creative.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.creatives.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/creatives",
	//   "request": {
	//     "$ref": "Creative"
	//   },
	//   "response": {
	//     "$ref": "Creative"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.dimensionValues.query":

type DimensionValuesQueryCall struct {
	s                     *Service
	profileId             int64
	dimensionvaluerequest *DimensionValueRequest
	urlParams_            gensupport.URLParams
	ctx_                  context.Context
}

// Query: Retrieves list of report dimension values for a list of
// filters.
func (r *DimensionValuesService) Query(profileId int64, dimensionvaluerequest *DimensionValueRequest) *DimensionValuesQueryCall {
	c := &DimensionValuesQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dimensionvaluerequest = dimensionvaluerequest
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *DimensionValuesQueryCall) MaxResults(maxResults int64) *DimensionValuesQueryCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *DimensionValuesQueryCall) PageToken(pageToken string) *DimensionValuesQueryCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DimensionValuesQueryCall) Fields(s ...googleapi.Field) *DimensionValuesQueryCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DimensionValuesQueryCall) Context(ctx context.Context) *DimensionValuesQueryCall {
	c.ctx_ = ctx
	return c
}

func (c *DimensionValuesQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.dimensionvaluerequest)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/dimensionvalues/query")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dimensionValues.query" call.
// Exactly one of *DimensionValueList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DimensionValueList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DimensionValuesQueryCall) Do(opts ...googleapi.CallOption) (*DimensionValueList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DimensionValueList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of report dimension values for a list of filters.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.dimensionValues.query",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "100",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dimensionvalues/query",
	//   "request": {
	//     "$ref": "DimensionValueRequest"
	//   },
	//   "response": {
	//     "$ref": "DimensionValueList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.directorySiteContacts.get":

type DirectorySiteContactsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one directory site contact by ID.
func (r *DirectorySiteContactsService) Get(profileId int64, id int64) *DirectorySiteContactsGetCall {
	c := &DirectorySiteContactsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySiteContactsGetCall) Fields(s ...googleapi.Field) *DirectorySiteContactsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DirectorySiteContactsGetCall) IfNoneMatch(entityTag string) *DirectorySiteContactsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DirectorySiteContactsGetCall) Context(ctx context.Context) *DirectorySiteContactsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *DirectorySiteContactsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/directorySiteContacts/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySiteContacts.get" call.
// Exactly one of *DirectorySiteContact or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DirectorySiteContact.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySiteContactsGetCall) Do(opts ...googleapi.CallOption) (*DirectorySiteContact, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySiteContact{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one directory site contact by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySiteContacts.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Directory site contact ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySiteContacts/{id}",
	//   "response": {
	//     "$ref": "DirectorySiteContact"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.directorySiteContacts.list":

type DirectorySiteContactsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of directory site contacts, possibly filtered.
func (r *DirectorySiteContactsService) List(profileId int64) *DirectorySiteContactsListCall {
	c := &DirectorySiteContactsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only directory site contacts with these directory site IDs.
// This is a required field.
func (c *DirectorySiteContactsListCall) DirectorySiteIds(directorySiteIds ...int64) *DirectorySiteContactsListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only directory site
// contacts with these IDs.
func (c *DirectorySiteContactsListCall) Ids(ids ...int64) *DirectorySiteContactsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *DirectorySiteContactsListCall) MaxResults(maxResults int64) *DirectorySiteContactsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *DirectorySiteContactsListCall) PageToken(pageToken string) *DirectorySiteContactsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or email. Wildcards (*) are
// allowed. For example, "directory site contact*2015" will return
// objects with names like "directory site contact June 2015",
// "directory site contact April 2015", or simply "directory site
// contact 2015". Most of the searches also add wildcards implicitly at
// the start and the end of the search string. For example, a search
// string of "directory site contact" will match objects with name "my
// directory site contact", "directory site contact 2015", or simply
// "directory site contact".
func (c *DirectorySiteContactsListCall) SearchString(searchString string) *DirectorySiteContactsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *DirectorySiteContactsListCall) SortField(sortField string) *DirectorySiteContactsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *DirectorySiteContactsListCall) SortOrder(sortOrder string) *DirectorySiteContactsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySiteContactsListCall) Fields(s ...googleapi.Field) *DirectorySiteContactsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DirectorySiteContactsListCall) IfNoneMatch(entityTag string) *DirectorySiteContactsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DirectorySiteContactsListCall) Context(ctx context.Context) *DirectorySiteContactsListCall {
	c.ctx_ = ctx
	return c
}

func (c *DirectorySiteContactsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/directorySiteContacts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySiteContacts.list" call.
// Exactly one of *DirectorySiteContactsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *DirectorySiteContactsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *DirectorySiteContactsListCall) Do(opts ...googleapi.CallOption) (*DirectorySiteContactsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySiteContactsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of directory site contacts, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySiteContacts.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "directorySiteIds": {
	//       "description": "Select only directory site contacts with these directory site IDs. This is a required field.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only directory site contacts with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or email. Wildcards (*) are allowed. For example, \"directory site contact*2015\" will return objects with names like \"directory site contact June 2015\", \"directory site contact April 2015\", or simply \"directory site contact 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"directory site contact\" will match objects with name \"my directory site contact\", \"directory site contact 2015\", or simply \"directory site contact\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySiteContacts",
	//   "response": {
	//     "$ref": "DirectorySiteContactsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DirectorySiteContactsListCall) Pages(ctx context.Context, f func(*DirectorySiteContactsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.directorySites.get":

type DirectorySitesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one directory site by ID.
func (r *DirectorySitesService) Get(profileId int64, id int64) *DirectorySitesGetCall {
	c := &DirectorySitesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySitesGetCall) Fields(s ...googleapi.Field) *DirectorySitesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DirectorySitesGetCall) IfNoneMatch(entityTag string) *DirectorySitesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DirectorySitesGetCall) Context(ctx context.Context) *DirectorySitesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *DirectorySitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/directorySites/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySites.get" call.
// Exactly one of *DirectorySite or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *DirectorySite.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySitesGetCall) Do(opts ...googleapi.CallOption) (*DirectorySite, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySite{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one directory site by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySites.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Directory site ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites/{id}",
	//   "response": {
	//     "$ref": "DirectorySite"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.directorySites.list":

type DirectorySitesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of directory sites, possibly filtered.
func (r *DirectorySitesService) List(profileId int64) *DirectorySitesListCall {
	c := &DirectorySitesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AcceptsInStreamVideoPlacements sets the optional parameter
// "acceptsInStreamVideoPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *DirectorySitesListCall) AcceptsInStreamVideoPlacements(acceptsInStreamVideoPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsInStreamVideoPlacements", fmt.Sprint(acceptsInStreamVideoPlacements))
	return c
}

// AcceptsInterstitialPlacements sets the optional parameter
// "acceptsInterstitialPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *DirectorySitesListCall) AcceptsInterstitialPlacements(acceptsInterstitialPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsInterstitialPlacements", fmt.Sprint(acceptsInterstitialPlacements))
	return c
}

// AcceptsPublisherPaidPlacements sets the optional parameter
// "acceptsPublisherPaidPlacements": Select only directory sites that
// accept publisher paid placements. This field can be left blank.
func (c *DirectorySitesListCall) AcceptsPublisherPaidPlacements(acceptsPublisherPaidPlacements bool) *DirectorySitesListCall {
	c.urlParams_.Set("acceptsPublisherPaidPlacements", fmt.Sprint(acceptsPublisherPaidPlacements))
	return c
}

// Active sets the optional parameter "active": Select only active
// directory sites. Leave blank to retrieve both active and inactive
// directory sites.
func (c *DirectorySitesListCall) Active(active bool) *DirectorySitesListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// CountryId sets the optional parameter "countryId": Select only
// directory sites with this country ID.
func (c *DirectorySitesListCall) CountryId(countryId int64) *DirectorySitesListCall {
	c.urlParams_.Set("countryId", fmt.Sprint(countryId))
	return c
}

// DfpNetworkCode sets the optional parameter "dfp_network_code": Select
// only directory sites with this DFP network code.
func (c *DirectorySitesListCall) DfpNetworkCode(dfpNetworkCode string) *DirectorySitesListCall {
	c.urlParams_.Set("dfp_network_code", dfpNetworkCode)
	return c
}

// Ids sets the optional parameter "ids": Select only directory sites
// with these IDs.
func (c *DirectorySitesListCall) Ids(ids ...int64) *DirectorySitesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *DirectorySitesListCall) MaxResults(maxResults int64) *DirectorySitesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *DirectorySitesListCall) PageToken(pageToken string) *DirectorySitesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// ParentId sets the optional parameter "parentId": Select only
// directory sites with this parent ID.
func (c *DirectorySitesListCall) ParentId(parentId int64) *DirectorySitesListCall {
	c.urlParams_.Set("parentId", fmt.Sprint(parentId))
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or URL. Wildcards (*) are allowed.
// For example, "directory site*2015" will return objects with names
// like "directory site June 2015", "directory site April 2015", or
// simply "directory site 2015". Most of the searches also add wildcards
// implicitly at the start and the end of the search string. For
// example, a search string of "directory site" will match objects with
// name "my directory site", "directory site 2015" or simply, "directory
// site".
func (c *DirectorySitesListCall) SearchString(searchString string) *DirectorySitesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *DirectorySitesListCall) SortField(sortField string) *DirectorySitesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *DirectorySitesListCall) SortOrder(sortOrder string) *DirectorySitesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *DirectorySitesListCall) Fields(s ...googleapi.Field) *DirectorySitesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *DirectorySitesListCall) IfNoneMatch(entityTag string) *DirectorySitesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *DirectorySitesListCall) Context(ctx context.Context) *DirectorySitesListCall {
	c.ctx_ = ctx
	return c
}

func (c *DirectorySitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/directorySites")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.directorySites.list" call.
// Exactly one of *DirectorySitesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *DirectorySitesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *DirectorySitesListCall) Do(opts ...googleapi.CallOption) (*DirectorySitesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &DirectorySitesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of directory sites, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.directorySites.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "acceptsInStreamVideoPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsInterstitialPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsPublisherPaidPlacements": {
	//       "description": "Select only directory sites that accept publisher paid placements. This field can be left blank.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "active": {
	//       "description": "Select only active directory sites. Leave blank to retrieve both active and inactive directory sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "countryId": {
	//       "description": "Select only directory sites with this country ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "dfp_network_code": {
	//       "description": "Select only directory sites with this DFP network code.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only directory sites with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "parentId": {
	//       "description": "Select only directory sites with this parent ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or URL. Wildcards (*) are allowed. For example, \"directory site*2015\" will return objects with names like \"directory site June 2015\", \"directory site April 2015\", or simply \"directory site 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"directory site\" will match objects with name \"my directory site\", \"directory site 2015\" or simply, \"directory site\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites",
	//   "response": {
	//     "$ref": "DirectorySitesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *DirectorySitesListCall) Pages(ctx context.Context, f func(*DirectorySitesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.eventTags.delete":

type EventTagsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing event tag.
func (r *EventTagsService) Delete(profileId int64, id int64) *EventTagsDeleteCall {
	c := &EventTagsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsDeleteCall) Fields(s ...googleapi.Field) *EventTagsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsDeleteCall) Context(ctx context.Context) *EventTagsDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.delete" call.
func (c *EventTagsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing event tag.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.eventTags.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Event tag ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.get":

type EventTagsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one event tag by ID.
func (r *EventTagsService) Get(profileId int64, id int64) *EventTagsGetCall {
	c := &EventTagsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsGetCall) Fields(s ...googleapi.Field) *EventTagsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *EventTagsGetCall) IfNoneMatch(entityTag string) *EventTagsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsGetCall) Context(ctx context.Context) *EventTagsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.get" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsGetCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one event tag by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.eventTags.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Event tag ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags/{id}",
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.insert":

type EventTagsInsertCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new event tag.
func (r *EventTagsService) Insert(profileId int64, eventtag *EventTag) *EventTagsInsertCall {
	c := &EventTagsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.eventtag = eventtag
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsInsertCall) Fields(s ...googleapi.Field) *EventTagsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsInsertCall) Context(ctx context.Context) *EventTagsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.eventtag)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.insert" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsInsertCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new event tag.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.eventTags.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.list":

type EventTagsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of event tags, possibly filtered.
func (r *EventTagsService) List(profileId int64) *EventTagsListCall {
	c := &EventTagsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdId sets the optional parameter "adId": Select only event tags that
// belong to this ad.
func (c *EventTagsListCall) AdId(adId int64) *EventTagsListCall {
	c.urlParams_.Set("adId", fmt.Sprint(adId))
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// event tags that belong to this advertiser.
func (c *EventTagsListCall) AdvertiserId(advertiserId int64) *EventTagsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// CampaignId sets the optional parameter "campaignId": Select only
// event tags that belong to this campaign.
func (c *EventTagsListCall) CampaignId(campaignId int64) *EventTagsListCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// DefinitionsOnly sets the optional parameter "definitionsOnly":
// Examine only the specified campaign or advertiser's event tags for
// matching selector criteria. When set to false, the parent advertiser
// and parent campaign of the specified ad or campaign is examined as
// well. In addition, when set to false, the status field is examined as
// well, along with the enabledByDefault field. This parameter can not
// be set to true when adId is specified as ads do not define their own
// even tags.
func (c *EventTagsListCall) DefinitionsOnly(definitionsOnly bool) *EventTagsListCall {
	c.urlParams_.Set("definitionsOnly", fmt.Sprint(definitionsOnly))
	return c
}

// Enabled sets the optional parameter "enabled": Select only enabled
// event tags. What is considered enabled or disabled depends on the
// definitionsOnly parameter. When definitionsOnly is set to true, only
// the specified advertiser or campaign's event tags' enabledByDefault
// field is examined. When definitionsOnly is set to false, the
// specified ad or specified campaign's parent advertiser's or parent
// campaign's event tags' enabledByDefault and status fields are
// examined as well.
func (c *EventTagsListCall) Enabled(enabled bool) *EventTagsListCall {
	c.urlParams_.Set("enabled", fmt.Sprint(enabled))
	return c
}

// EventTagTypes sets the optional parameter "eventTagTypes": Select
// only event tags with the specified event tag types. Event tag types
// can be used to specify whether to use a third-party pixel, a
// third-party JavaScript URL, or a third-party click-through URL for
// either impression or click tracking.
//
// Possible values:
//   "CLICK_THROUGH_EVENT_TAG"
//   "IMPRESSION_IMAGE_EVENT_TAG"
//   "IMPRESSION_JAVASCRIPT_EVENT_TAG"
func (c *EventTagsListCall) EventTagTypes(eventTagTypes ...string) *EventTagsListCall {
	c.urlParams_.SetMulti("eventTagTypes", append([]string{}, eventTagTypes...))
	return c
}

// Ids sets the optional parameter "ids": Select only event tags with
// these IDs.
func (c *EventTagsListCall) Ids(ids ...int64) *EventTagsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "eventtag*2015" will return objects with names like
// "eventtag June 2015", "eventtag April 2015", or simply "eventtag
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "eventtag" will match objects with name "my eventtag", "eventtag
// 2015", or simply "eventtag".
func (c *EventTagsListCall) SearchString(searchString string) *EventTagsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *EventTagsListCall) SortField(sortField string) *EventTagsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *EventTagsListCall) SortOrder(sortOrder string) *EventTagsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsListCall) Fields(s ...googleapi.Field) *EventTagsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *EventTagsListCall) IfNoneMatch(entityTag string) *EventTagsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsListCall) Context(ctx context.Context) *EventTagsListCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.list" call.
// Exactly one of *EventTagsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *EventTagsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *EventTagsListCall) Do(opts ...googleapi.CallOption) (*EventTagsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTagsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of event tags, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.eventTags.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "adId": {
	//       "description": "Select only event tags that belong to this ad.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "advertiserId": {
	//       "description": "Select only event tags that belong to this advertiser.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "campaignId": {
	//       "description": "Select only event tags that belong to this campaign.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "definitionsOnly": {
	//       "description": "Examine only the specified campaign or advertiser's event tags for matching selector criteria. When set to false, the parent advertiser and parent campaign of the specified ad or campaign is examined as well. In addition, when set to false, the status field is examined as well, along with the enabledByDefault field. This parameter can not be set to true when adId is specified as ads do not define their own even tags.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "enabled": {
	//       "description": "Select only enabled event tags. What is considered enabled or disabled depends on the definitionsOnly parameter. When definitionsOnly is set to true, only the specified advertiser or campaign's event tags' enabledByDefault field is examined. When definitionsOnly is set to false, the specified ad or specified campaign's parent advertiser's or parent campaign's event tags' enabledByDefault and status fields are examined as well.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "eventTagTypes": {
	//       "description": "Select only event tags with the specified event tag types. Event tag types can be used to specify whether to use a third-party pixel, a third-party JavaScript URL, or a third-party click-through URL for either impression or click tracking.",
	//       "enum": [
	//         "CLICK_THROUGH_EVENT_TAG",
	//         "IMPRESSION_IMAGE_EVENT_TAG",
	//         "IMPRESSION_JAVASCRIPT_EVENT_TAG"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only event tags with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"eventtag*2015\" will return objects with names like \"eventtag June 2015\", \"eventtag April 2015\", or simply \"eventtag 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"eventtag\" will match objects with name \"my eventtag\", \"eventtag 2015\", or simply \"eventtag\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "response": {
	//     "$ref": "EventTagsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.patch":

type EventTagsPatchCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing event tag. This method supports patch
// semantics.
func (r *EventTagsService) Patch(profileId int64, id int64, eventtag *EventTag) *EventTagsPatchCall {
	c := &EventTagsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.eventtag = eventtag
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsPatchCall) Fields(s ...googleapi.Field) *EventTagsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsPatchCall) Context(ctx context.Context) *EventTagsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.eventtag)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.patch" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsPatchCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing event tag. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.eventTags.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Event tag ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.update":

type EventTagsUpdateCall struct {
	s          *Service
	profileId  int64
	eventtag   *EventTag
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing event tag.
func (r *EventTagsService) Update(profileId int64, eventtag *EventTag) *EventTagsUpdateCall {
	c := &EventTagsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.eventtag = eventtag
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *EventTagsUpdateCall) Fields(s ...googleapi.Field) *EventTagsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *EventTagsUpdateCall) Context(ctx context.Context) *EventTagsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *EventTagsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.eventtag)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/eventTags")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.eventTags.update" call.
// Exactly one of *EventTag or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *EventTag.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *EventTagsUpdateCall) Do(opts ...googleapi.CallOption) (*EventTag, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &EventTag{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing event tag.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.eventTags.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/eventTags",
	//   "request": {
	//     "$ref": "EventTag"
	//   },
	//   "response": {
	//     "$ref": "EventTag"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.files.get":

type FilesGetCall struct {
	s            *Service
	reportId     int64
	fileId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Retrieves a report file by its report ID and file ID.
func (r *FilesService) Get(reportId int64, fileId int64) *FilesGetCall {
	c := &FilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.reportId = reportId
	c.fileId = fileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FilesGetCall) Fields(s ...googleapi.Field) *FilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FilesGetCall) IfNoneMatch(entityTag string) *FilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *FilesGetCall) Context(ctx context.Context) *FilesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *FilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "reports/{reportId}/files/{fileId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"reportId": strconv.FormatInt(c.reportId, 10),
		"fileId":   strconv.FormatInt(c.fileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *FilesGetCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "dfareporting.files.get" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FilesGetCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file by its report ID and file ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.files.get",
	//   "parameterOrder": [
	//     "reportId",
	//     "fileId"
	//   ],
	//   "parameters": {
	//     "fileId": {
	//       "description": "The ID of the report file.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "reports/{reportId}/files/{fileId}",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "dfareporting.files.list":

type FilesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Lists files for a user profile.
func (r *FilesService) List(profileId int64) *FilesListCall {
	c := &FilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FilesListCall) MaxResults(maxResults int64) *FilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *FilesListCall) PageToken(pageToken string) *FilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Scope sets the optional parameter "scope": The scope that defines
// which results are returned, default is 'MINE'.
//
// Possible values:
//   "ALL" - All files in account.
//   "MINE" (default) - My files.
//   "SHARED_WITH_ME" - Files shared with me.
func (c *FilesListCall) Scope(scope string) *FilesListCall {
	c.urlParams_.Set("scope", scope)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID" - Sort by file ID.
//   "LAST_MODIFIED_TIME" (default) - Sort by 'lastmodifiedAt' field.
func (c *FilesListCall) SortField(sortField string) *FilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is 'DESCENDING'.
//
// Possible values:
//   "ASCENDING" - Ascending order.
//   "DESCENDING" (default) - Descending order.
func (c *FilesListCall) SortOrder(sortOrder string) *FilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FilesListCall) Fields(s ...googleapi.Field) *FilesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FilesListCall) IfNoneMatch(entityTag string) *FilesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FilesListCall) Context(ctx context.Context) *FilesListCall {
	c.ctx_ = ctx
	return c
}

func (c *FilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/files")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.files.list" call.
// Exactly one of *FileList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *FileList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *FilesListCall) Do(opts ...googleapi.CallOption) (*FileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FileList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists files for a user profile.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.files.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scope": {
	//       "default": "MINE",
	//       "description": "The scope that defines which results are returned, default is 'MINE'.",
	//       "enum": [
	//         "ALL",
	//         "MINE",
	//         "SHARED_WITH_ME"
	//       ],
	//       "enumDescriptions": [
	//         "All files in account.",
	//         "My files.",
	//         "Files shared with me."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME"
	//       ],
	//       "enumDescriptions": [
	//         "Sort by file ID.",
	//         "Sort by 'lastmodifiedAt' field."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results, default is 'DESCENDING'.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "Ascending order.",
	//         "Descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/files",
	//   "response": {
	//     "$ref": "FileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FilesListCall) Pages(ctx context.Context, f func(*FileList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.floodlightActivities.delete":

type FloodlightActivitiesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing floodlight activity.
func (r *FloodlightActivitiesService) Delete(profileId int64, id int64) *FloodlightActivitiesDeleteCall {
	c := &FloodlightActivitiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesDeleteCall) Fields(s ...googleapi.Field) *FloodlightActivitiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesDeleteCall) Context(ctx context.Context) *FloodlightActivitiesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.delete" call.
func (c *FloodlightActivitiesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing floodlight activity.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.floodlightActivities.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.generatetag":

type FloodlightActivitiesGeneratetagCall struct {
	s          *Service
	profileId  int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Generatetag: Generates a tag for a floodlight activity.
func (r *FloodlightActivitiesService) Generatetag(profileId int64) *FloodlightActivitiesGeneratetagCall {
	c := &FloodlightActivitiesGeneratetagCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// FloodlightActivityId sets the optional parameter
// "floodlightActivityId": Floodlight activity ID for which we want to
// generate a tag.
func (c *FloodlightActivitiesGeneratetagCall) FloodlightActivityId(floodlightActivityId int64) *FloodlightActivitiesGeneratetagCall {
	c.urlParams_.Set("floodlightActivityId", fmt.Sprint(floodlightActivityId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesGeneratetagCall) Fields(s ...googleapi.Field) *FloodlightActivitiesGeneratetagCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesGeneratetagCall) Context(ctx context.Context) *FloodlightActivitiesGeneratetagCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesGeneratetagCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities/generatetag")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.generatetag" call.
// Exactly one of *FloodlightActivitiesGenerateTagResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *FloodlightActivitiesGenerateTagResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesGeneratetagCall) Do(opts ...googleapi.CallOption) (*FloodlightActivitiesGenerateTagResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivitiesGenerateTagResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates a tag for a floodlight activity.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivities.generatetag",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "floodlightActivityId": {
	//       "description": "Floodlight activity ID for which we want to generate a tag.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/generatetag",
	//   "response": {
	//     "$ref": "FloodlightActivitiesGenerateTagResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.get":

type FloodlightActivitiesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one floodlight activity by ID.
func (r *FloodlightActivitiesService) Get(profileId int64, id int64) *FloodlightActivitiesGetCall {
	c := &FloodlightActivitiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesGetCall) Fields(s ...googleapi.Field) *FloodlightActivitiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightActivitiesGetCall) IfNoneMatch(entityTag string) *FloodlightActivitiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesGetCall) Context(ctx context.Context) *FloodlightActivitiesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.get" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesGetCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one floodlight activity by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivities.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities/{id}",
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.insert":

type FloodlightActivitiesInsertCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Insert: Inserts a new floodlight activity.
func (r *FloodlightActivitiesService) Insert(profileId int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesInsertCall {
	c := &FloodlightActivitiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivity = floodlightactivity
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesInsertCall) Fields(s ...googleapi.Field) *FloodlightActivitiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesInsertCall) Context(ctx context.Context) *FloodlightActivitiesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivity)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.insert" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesInsertCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new floodlight activity.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivities.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.list":

type FloodlightActivitiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of floodlight activities, possibly filtered.
func (r *FloodlightActivitiesService) List(profileId int64) *FloodlightActivitiesListCall {
	c := &FloodlightActivitiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// floodlight activities for the specified advertiser ID. Must specify
// either ids, advertiserId, or floodlightConfigurationId for a
// non-empty result.
func (c *FloodlightActivitiesListCall) AdvertiserId(advertiserId int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// FloodlightActivityGroupIds sets the optional parameter
// "floodlightActivityGroupIds": Select only floodlight activities with
// the specified floodlight activity group IDs.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupIds(floodlightActivityGroupIds ...int64) *FloodlightActivitiesListCall {
	var floodlightActivityGroupIds_ []string
	for _, v := range floodlightActivityGroupIds {
		floodlightActivityGroupIds_ = append(floodlightActivityGroupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("floodlightActivityGroupIds", floodlightActivityGroupIds_)
	return c
}

// FloodlightActivityGroupName sets the optional parameter
// "floodlightActivityGroupName": Select only floodlight activities with
// the specified floodlight activity group name.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupName(floodlightActivityGroupName string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupName", floodlightActivityGroupName)
	return c
}

// FloodlightActivityGroupTagString sets the optional parameter
// "floodlightActivityGroupTagString": Select only floodlight activities
// with the specified floodlight activity group tag string.
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupTagString(floodlightActivityGroupTagString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupTagString", floodlightActivityGroupTagString)
	return c
}

// FloodlightActivityGroupType sets the optional parameter
// "floodlightActivityGroupType": Select only floodlight activities with
// the specified floodlight activity group type.
//
// Possible values:
//   "COUNTER"
//   "SALE"
func (c *FloodlightActivitiesListCall) FloodlightActivityGroupType(floodlightActivityGroupType string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightActivityGroupType", floodlightActivityGroupType)
	return c
}

// FloodlightConfigurationId sets the optional parameter
// "floodlightConfigurationId": Select only floodlight activities for
// the specified floodlight configuration ID. Must specify either ids,
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivitiesListCall) FloodlightConfigurationId(floodlightConfigurationId int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("floodlightConfigurationId", fmt.Sprint(floodlightConfigurationId))
	return c
}

// Ids sets the optional parameter "ids": Select only floodlight
// activities with the specified IDs. Must specify either ids,
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivitiesListCall) Ids(ids ...int64) *FloodlightActivitiesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FloodlightActivitiesListCall) MaxResults(maxResults int64) *FloodlightActivitiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *FloodlightActivitiesListCall) PageToken(pageToken string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "floodlightactivity*2015" will return objects with names
// like "floodlightactivity June 2015", "floodlightactivity April 2015",
// or simply "floodlightactivity 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "floodlightactivity" will match
// objects with name "my floodlightactivity activity",
// "floodlightactivity 2015", or simply "floodlightactivity".
func (c *FloodlightActivitiesListCall) SearchString(searchString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *FloodlightActivitiesListCall) SortField(sortField string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *FloodlightActivitiesListCall) SortOrder(sortOrder string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// TagString sets the optional parameter "tagString": Select only
// floodlight activities with the specified tag string.
func (c *FloodlightActivitiesListCall) TagString(tagString string) *FloodlightActivitiesListCall {
	c.urlParams_.Set("tagString", tagString)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesListCall) Fields(s ...googleapi.Field) *FloodlightActivitiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightActivitiesListCall) IfNoneMatch(entityTag string) *FloodlightActivitiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesListCall) Context(ctx context.Context) *FloodlightActivitiesListCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.list" call.
// Exactly one of *FloodlightActivitiesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightActivitiesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesListCall) Do(opts ...googleapi.CallOption) (*FloodlightActivitiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivitiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activities, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivities.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only floodlight activities for the specified advertiser ID. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupIds": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupName": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group name.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupTagString": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group tag string.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightActivityGroupType": {
	//       "description": "Select only floodlight activities with the specified floodlight activity group type.",
	//       "enum": [
	//         "COUNTER",
	//         "SALE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightConfigurationId": {
	//       "description": "Select only floodlight activities for the specified floodlight configuration ID. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only floodlight activities with the specified IDs. Must specify either ids, advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"floodlightactivity*2015\" will return objects with names like \"floodlightactivity June 2015\", \"floodlightactivity April 2015\", or simply \"floodlightactivity 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"floodlightactivity\" will match objects with name \"my floodlightactivity activity\", \"floodlightactivity 2015\", or simply \"floodlightactivity\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "tagString": {
	//       "description": "Select only floodlight activities with the specified tag string.",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "response": {
	//     "$ref": "FloodlightActivitiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FloodlightActivitiesListCall) Pages(ctx context.Context, f func(*FloodlightActivitiesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.floodlightActivities.patch":

type FloodlightActivitiesPatchCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Patch: Updates an existing floodlight activity. This method supports
// patch semantics.
func (r *FloodlightActivitiesService) Patch(profileId int64, id int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesPatchCall {
	c := &FloodlightActivitiesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.floodlightactivity = floodlightactivity
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesPatchCall) Fields(s ...googleapi.Field) *FloodlightActivitiesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesPatchCall) Context(ctx context.Context) *FloodlightActivitiesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivity)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.patch" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight activity. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightActivities.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivities.update":

type FloodlightActivitiesUpdateCall struct {
	s                  *Service
	profileId          int64
	floodlightactivity *FloodlightActivity
	urlParams_         gensupport.URLParams
	ctx_               context.Context
}

// Update: Updates an existing floodlight activity.
func (r *FloodlightActivitiesService) Update(profileId int64, floodlightactivity *FloodlightActivity) *FloodlightActivitiesUpdateCall {
	c := &FloodlightActivitiesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivity = floodlightactivity
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivitiesUpdateCall) Fields(s ...googleapi.Field) *FloodlightActivitiesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivitiesUpdateCall) Context(ctx context.Context) *FloodlightActivitiesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivitiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivity)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivities")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivities.update" call.
// Exactly one of *FloodlightActivity or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivity.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivitiesUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightActivity, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivity{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight activity.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightActivities.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivities",
	//   "request": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivity"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.delete":

type FloodlightActivityGroupsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing floodlight activity group.
func (r *FloodlightActivityGroupsService) Delete(profileId int64, id int64) *FloodlightActivityGroupsDeleteCall {
	c := &FloodlightActivityGroupsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsDeleteCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsDeleteCall) Context(ctx context.Context) *FloodlightActivityGroupsDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.delete" call.
func (c *FloodlightActivityGroupsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing floodlight activity group.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.floodlightActivityGroups.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity Group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.get":

type FloodlightActivityGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one floodlight activity group by ID.
func (r *FloodlightActivityGroupsService) Get(profileId int64, id int64) *FloodlightActivityGroupsGetCall {
	c := &FloodlightActivityGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsGetCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightActivityGroupsGetCall) IfNoneMatch(entityTag string) *FloodlightActivityGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsGetCall) Context(ctx context.Context) *FloodlightActivityGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.get" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsGetCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one floodlight activity group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivityGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity Group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups/{id}",
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.insert":

type FloodlightActivityGroupsInsertCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
}

// Insert: Inserts a new floodlight activity group.
func (r *FloodlightActivityGroupsService) Insert(profileId int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsInsertCall {
	c := &FloodlightActivityGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsInsertCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsInsertCall) Context(ctx context.Context) *FloodlightActivityGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivitygroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.insert" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsInsertCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new floodlight activity group.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.floodlightActivityGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.list":

type FloodlightActivityGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of floodlight activity groups, possibly
// filtered.
func (r *FloodlightActivityGroupsService) List(profileId int64) *FloodlightActivityGroupsListCall {
	c := &FloodlightActivityGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// floodlight activity groups with the specified advertiser ID. Must
// specify either advertiserId or floodlightConfigurationId for a
// non-empty result.
func (c *FloodlightActivityGroupsListCall) AdvertiserId(advertiserId int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// FloodlightConfigurationId sets the optional parameter
// "floodlightConfigurationId": Select only floodlight activity groups
// with the specified floodlight configuration ID. Must specify either
// advertiserId, or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivityGroupsListCall) FloodlightConfigurationId(floodlightConfigurationId int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("floodlightConfigurationId", fmt.Sprint(floodlightConfigurationId))
	return c
}

// Ids sets the optional parameter "ids": Select only floodlight
// activity groups with the specified IDs. Must specify either
// advertiserId or floodlightConfigurationId for a non-empty result.
func (c *FloodlightActivityGroupsListCall) Ids(ids ...int64) *FloodlightActivityGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *FloodlightActivityGroupsListCall) MaxResults(maxResults int64) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *FloodlightActivityGroupsListCall) PageToken(pageToken string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "floodlightactivitygroup*2015" will return objects with
// names like "floodlightactivitygroup June 2015",
// "floodlightactivitygroup April 2015", or simply
// "floodlightactivitygroup 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "floodlightactivitygroup" will match
// objects with name "my floodlightactivitygroup activity",
// "floodlightactivitygroup 2015", or simply "floodlightactivitygroup".
func (c *FloodlightActivityGroupsListCall) SearchString(searchString string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *FloodlightActivityGroupsListCall) SortField(sortField string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *FloodlightActivityGroupsListCall) SortOrder(sortOrder string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Type sets the optional parameter "type": Select only floodlight
// activity groups with the specified floodlight activity group type.
//
// Possible values:
//   "COUNTER"
//   "SALE"
func (c *FloodlightActivityGroupsListCall) Type(type_ string) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("type", type_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsListCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightActivityGroupsListCall) IfNoneMatch(entityTag string) *FloodlightActivityGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsListCall) Context(ctx context.Context) *FloodlightActivityGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.list" call.
// Exactly one of *FloodlightActivityGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightActivityGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FloodlightActivityGroupsListCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activity groups, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightActivityGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only floodlight activity groups with the specified advertiser ID. Must specify either advertiserId or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "floodlightConfigurationId": {
	//       "description": "Select only floodlight activity groups with the specified floodlight configuration ID. Must specify either advertiserId, or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only floodlight activity groups with the specified IDs. Must specify either advertiserId or floodlightConfigurationId for a non-empty result.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"floodlightactivitygroup*2015\" will return objects with names like \"floodlightactivitygroup June 2015\", \"floodlightactivitygroup April 2015\", or simply \"floodlightactivitygroup 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"floodlightactivitygroup\" will match objects with name \"my floodlightactivitygroup activity\", \"floodlightactivitygroup 2015\", or simply \"floodlightactivitygroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Select only floodlight activity groups with the specified floodlight activity group type.",
	//       "enum": [
	//         "COUNTER",
	//         "SALE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "response": {
	//     "$ref": "FloodlightActivityGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *FloodlightActivityGroupsListCall) Pages(ctx context.Context, f func(*FloodlightActivityGroupsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.floodlightActivityGroups.patch":

type FloodlightActivityGroupsPatchCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
}

// Patch: Updates an existing floodlight activity group. This method
// supports patch semantics.
func (r *FloodlightActivityGroupsService) Patch(profileId int64, id int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsPatchCall {
	c := &FloodlightActivityGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsPatchCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsPatchCall) Context(ctx context.Context) *FloodlightActivityGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivitygroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.patch" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight activity group. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightActivityGroups.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight activity Group ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightActivityGroups.update":

type FloodlightActivityGroupsUpdateCall struct {
	s                       *Service
	profileId               int64
	floodlightactivitygroup *FloodlightActivityGroup
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
}

// Update: Updates an existing floodlight activity group.
func (r *FloodlightActivityGroupsService) Update(profileId int64, floodlightactivitygroup *FloodlightActivityGroup) *FloodlightActivityGroupsUpdateCall {
	c := &FloodlightActivityGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightactivitygroup = floodlightactivitygroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightActivityGroupsUpdateCall) Fields(s ...googleapi.Field) *FloodlightActivityGroupsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightActivityGroupsUpdateCall) Context(ctx context.Context) *FloodlightActivityGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightActivityGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightactivitygroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightActivityGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightActivityGroups.update" call.
// Exactly one of *FloodlightActivityGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightActivityGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightActivityGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightActivityGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightActivityGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight activity group.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightActivityGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightActivityGroups",
	//   "request": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "response": {
	//     "$ref": "FloodlightActivityGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.get":

type FloodlightConfigurationsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one floodlight configuration by ID.
func (r *FloodlightConfigurationsService) Get(profileId int64, id int64) *FloodlightConfigurationsGetCall {
	c := &FloodlightConfigurationsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsGetCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightConfigurationsGetCall) IfNoneMatch(entityTag string) *FloodlightConfigurationsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightConfigurationsGetCall) Context(ctx context.Context) *FloodlightConfigurationsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightConfigurationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightConfigurations/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.get" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsGetCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one floodlight configuration by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightConfigurations.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight configuration ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations/{id}",
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.list":

type FloodlightConfigurationsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of floodlight configurations, possibly
// filtered.
func (r *FloodlightConfigurationsService) List(profileId int64) *FloodlightConfigurationsListCall {
	c := &FloodlightConfigurationsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Set of IDs of floodlight
// configurations to retrieve. Required field; otherwise an empty list
// will be returned.
func (c *FloodlightConfigurationsListCall) Ids(ids ...int64) *FloodlightConfigurationsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsListCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *FloodlightConfigurationsListCall) IfNoneMatch(entityTag string) *FloodlightConfigurationsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightConfigurationsListCall) Context(ctx context.Context) *FloodlightConfigurationsListCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightConfigurationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightConfigurations")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.list" call.
// Exactly one of *FloodlightConfigurationsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *FloodlightConfigurationsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *FloodlightConfigurationsListCall) Do(opts ...googleapi.CallOption) (*FloodlightConfigurationsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfigurationsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight configurations, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.floodlightConfigurations.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Set of IDs of floodlight configurations to retrieve. Required field; otherwise an empty list will be returned.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "response": {
	//     "$ref": "FloodlightConfigurationsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.patch":

type FloodlightConfigurationsPatchCall struct {
	s                       *Service
	profileId               int64
	floodlightconfiguration *FloodlightConfiguration
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
}

// Patch: Updates an existing floodlight configuration. This method
// supports patch semantics.
func (r *FloodlightConfigurationsService) Patch(profileId int64, id int64, floodlightconfiguration *FloodlightConfiguration) *FloodlightConfigurationsPatchCall {
	c := &FloodlightConfigurationsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.floodlightconfiguration = floodlightconfiguration
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsPatchCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightConfigurationsPatchCall) Context(ctx context.Context) *FloodlightConfigurationsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightConfigurationsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightconfiguration)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightConfigurations")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.patch" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsPatchCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight configuration. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.floodlightConfigurations.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Floodlight configuration ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "request": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.floodlightConfigurations.update":

type FloodlightConfigurationsUpdateCall struct {
	s                       *Service
	profileId               int64
	floodlightconfiguration *FloodlightConfiguration
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
}

// Update: Updates an existing floodlight configuration.
func (r *FloodlightConfigurationsService) Update(profileId int64, floodlightconfiguration *FloodlightConfiguration) *FloodlightConfigurationsUpdateCall {
	c := &FloodlightConfigurationsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.floodlightconfiguration = floodlightconfiguration
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *FloodlightConfigurationsUpdateCall) Fields(s ...googleapi.Field) *FloodlightConfigurationsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *FloodlightConfigurationsUpdateCall) Context(ctx context.Context) *FloodlightConfigurationsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *FloodlightConfigurationsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.floodlightconfiguration)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/floodlightConfigurations")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.floodlightConfigurations.update" call.
// Exactly one of *FloodlightConfiguration or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *FloodlightConfiguration.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *FloodlightConfigurationsUpdateCall) Do(opts ...googleapi.CallOption) (*FloodlightConfiguration, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FloodlightConfiguration{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing floodlight configuration.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.floodlightConfigurations.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/floodlightConfigurations",
	//   "request": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "response": {
	//     "$ref": "FloodlightConfiguration"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.delete":

type LandingPagesDeleteCall struct {
	s          *Service
	profileId  int64
	campaignId int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing campaign landing page.
func (r *LandingPagesService) Delete(profileId int64, campaignId int64, id int64) *LandingPagesDeleteCall {
	c := &LandingPagesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesDeleteCall) Fields(s ...googleapi.Field) *LandingPagesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesDeleteCall) Context(ctx context.Context) *LandingPagesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
		"id":         strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.delete" call.
func (c *LandingPagesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing campaign landing page.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.landingPages.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Landing page ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.get":

type LandingPagesGetCall struct {
	s            *Service
	profileId    int64
	campaignId   int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one campaign landing page by ID.
func (r *LandingPagesService) Get(profileId int64, campaignId int64, id int64) *LandingPagesGetCall {
	c := &LandingPagesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesGetCall) Fields(s ...googleapi.Field) *LandingPagesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LandingPagesGetCall) IfNoneMatch(entityTag string) *LandingPagesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesGetCall) Context(ctx context.Context) *LandingPagesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
		"id":         strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.get" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LandingPagesGetCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one campaign landing page by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.landingPages.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Landing page ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages/{id}",
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.insert":

type LandingPagesInsertCall struct {
	s           *Service
	profileId   int64
	campaignId  int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
}

// Insert: Inserts a new landing page for the specified campaign.
func (r *LandingPagesService) Insert(profileId int64, campaignId int64, landingpage *LandingPage) *LandingPagesInsertCall {
	c := &LandingPagesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.landingpage = landingpage
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesInsertCall) Fields(s ...googleapi.Field) *LandingPagesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesInsertCall) Context(ctx context.Context) *LandingPagesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.landingpage)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.insert" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LandingPagesInsertCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new landing page for the specified campaign.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.landingPages.insert",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.list":

type LandingPagesListCall struct {
	s            *Service
	profileId    int64
	campaignId   int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves the list of landing pages for the specified campaign.
func (r *LandingPagesService) List(profileId int64, campaignId int64) *LandingPagesListCall {
	c := &LandingPagesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesListCall) Fields(s ...googleapi.Field) *LandingPagesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *LandingPagesListCall) IfNoneMatch(entityTag string) *LandingPagesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesListCall) Context(ctx context.Context) *LandingPagesListCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.list" call.
// Exactly one of *LandingPagesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *LandingPagesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LandingPagesListCall) Do(opts ...googleapi.CallOption) (*LandingPagesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPagesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of landing pages for the specified campaign.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.landingPages.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages",
	//   "response": {
	//     "$ref": "LandingPagesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.patch":

type LandingPagesPatchCall struct {
	s           *Service
	profileId   int64
	campaignId  int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
}

// Patch: Updates an existing campaign landing page. This method
// supports patch semantics.
func (r *LandingPagesService) Patch(profileId int64, campaignId int64, id int64, landingpage *LandingPage) *LandingPagesPatchCall {
	c := &LandingPagesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.landingpage = landingpage
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesPatchCall) Fields(s ...googleapi.Field) *LandingPagesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesPatchCall) Context(ctx context.Context) *LandingPagesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.landingpage)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.patch" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LandingPagesPatchCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing campaign landing page. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.landingPages.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "id": {
	//       "description": "Landing page ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.landingPages.update":

type LandingPagesUpdateCall struct {
	s           *Service
	profileId   int64
	campaignId  int64
	landingpage *LandingPage
	urlParams_  gensupport.URLParams
	ctx_        context.Context
}

// Update: Updates an existing campaign landing page.
func (r *LandingPagesService) Update(profileId int64, campaignId int64, landingpage *LandingPage) *LandingPagesUpdateCall {
	c := &LandingPagesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.campaignId = campaignId
	c.landingpage = landingpage
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LandingPagesUpdateCall) Fields(s ...googleapi.Field) *LandingPagesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *LandingPagesUpdateCall) Context(ctx context.Context) *LandingPagesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *LandingPagesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.landingpage)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/campaigns/{campaignId}/landingPages")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId":  strconv.FormatInt(c.profileId, 10),
		"campaignId": strconv.FormatInt(c.campaignId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.landingPages.update" call.
// Exactly one of *LandingPage or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *LandingPage.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *LandingPagesUpdateCall) Do(opts ...googleapi.CallOption) (*LandingPage, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LandingPage{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing campaign landing page.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.landingPages.update",
	//   "parameterOrder": [
	//     "profileId",
	//     "campaignId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Landing page campaign ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/campaigns/{campaignId}/landingPages",
	//   "request": {
	//     "$ref": "LandingPage"
	//   },
	//   "response": {
	//     "$ref": "LandingPage"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.metros.list":

type MetrosListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of metros.
func (r *MetrosService) List(profileId int64) *MetrosListCall {
	c := &MetrosListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MetrosListCall) Fields(s ...googleapi.Field) *MetrosListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *MetrosListCall) IfNoneMatch(entityTag string) *MetrosListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *MetrosListCall) Context(ctx context.Context) *MetrosListCall {
	c.ctx_ = ctx
	return c
}

func (c *MetrosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/metros")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.metros.list" call.
// Exactly one of *MetrosListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *MetrosListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MetrosListCall) Do(opts ...googleapi.CallOption) (*MetrosListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MetrosListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of metros.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.metros.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/metros",
	//   "response": {
	//     "$ref": "MetrosListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.mobileCarriers.list":

type MobileCarriersListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of mobile carriers.
func (r *MobileCarriersService) List(profileId int64) *MobileCarriersListCall {
	c := &MobileCarriersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *MobileCarriersListCall) Fields(s ...googleapi.Field) *MobileCarriersListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *MobileCarriersListCall) IfNoneMatch(entityTag string) *MobileCarriersListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *MobileCarriersListCall) Context(ctx context.Context) *MobileCarriersListCall {
	c.ctx_ = ctx
	return c
}

func (c *MobileCarriersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/mobileCarriers")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.mobileCarriers.list" call.
// Exactly one of *MobileCarriersListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *MobileCarriersListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *MobileCarriersListCall) Do(opts ...googleapi.CallOption) (*MobileCarriersListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &MobileCarriersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of mobile carriers.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileCarriers.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/mobileCarriers",
	//   "response": {
	//     "$ref": "MobileCarriersListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystemVersions.list":

type OperatingSystemVersionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of operating system versions.
func (r *OperatingSystemVersionsService) List(profileId int64) *OperatingSystemVersionsListCall {
	c := &OperatingSystemVersionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemVersionsListCall) Fields(s ...googleapi.Field) *OperatingSystemVersionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OperatingSystemVersionsListCall) IfNoneMatch(entityTag string) *OperatingSystemVersionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OperatingSystemVersionsListCall) Context(ctx context.Context) *OperatingSystemVersionsListCall {
	c.ctx_ = ctx
	return c
}

func (c *OperatingSystemVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/operatingSystemVersions")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystemVersions.list" call.
// Exactly one of *OperatingSystemVersionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *OperatingSystemVersionsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *OperatingSystemVersionsListCall) Do(opts ...googleapi.CallOption) (*OperatingSystemVersionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystemVersionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of operating system versions.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystemVersions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystemVersions",
	//   "response": {
	//     "$ref": "OperatingSystemVersionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.operatingSystems.list":

type OperatingSystemsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of operating systems.
func (r *OperatingSystemsService) List(profileId int64) *OperatingSystemsListCall {
	c := &OperatingSystemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *OperatingSystemsListCall) Fields(s ...googleapi.Field) *OperatingSystemsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *OperatingSystemsListCall) IfNoneMatch(entityTag string) *OperatingSystemsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *OperatingSystemsListCall) Context(ctx context.Context) *OperatingSystemsListCall {
	c.ctx_ = ctx
	return c
}

func (c *OperatingSystemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/operatingSystems")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.operatingSystems.list" call.
// Exactly one of *OperatingSystemsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *OperatingSystemsListResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *OperatingSystemsListCall) Do(opts ...googleapi.CallOption) (*OperatingSystemsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &OperatingSystemsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of operating systems.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystems.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/operatingSystems",
	//   "response": {
	//     "$ref": "OperatingSystemsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.get":

type PlacementGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one placement group by ID.
func (r *PlacementGroupsService) Get(profileId int64, id int64) *PlacementGroupsGetCall {
	c := &PlacementGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsGetCall) Fields(s ...googleapi.Field) *PlacementGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementGroupsGetCall) IfNoneMatch(entityTag string) *PlacementGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementGroupsGetCall) Context(ctx context.Context) *PlacementGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.get" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsGetCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one placement group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups/{id}",
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.insert":

type PlacementGroupsInsertCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
}

// Insert: Inserts a new placement group.
func (r *PlacementGroupsService) Insert(profileId int64, placementgroup *PlacementGroup) *PlacementGroupsInsertCall {
	c := &PlacementGroupsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementgroup = placementgroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsInsertCall) Fields(s ...googleapi.Field) *PlacementGroupsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementGroupsInsertCall) Context(ctx context.Context) *PlacementGroupsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.insert" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsInsertCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement group.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placementGroups.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.list":

type PlacementGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of placement groups, possibly filtered.
func (r *PlacementGroupsService) List(profileId int64) *PlacementGroupsListCall {
	c := &PlacementGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only placement groups that belong to these advertisers.
func (c *PlacementGroupsListCall) AdvertiserIds(advertiserIds ...int64) *PlacementGroupsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// placements. Don't set this field to select both archived and
// non-archived placements.
func (c *PlacementGroupsListCall) Archived(archived bool) *PlacementGroupsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// placement groups that belong to these campaigns.
func (c *PlacementGroupsListCall) CampaignIds(campaignIds ...int64) *PlacementGroupsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// ContentCategoryIds sets the optional parameter "contentCategoryIds":
// Select only placement groups that are associated with these content
// categories.
func (c *PlacementGroupsListCall) ContentCategoryIds(contentCategoryIds ...int64) *PlacementGroupsListCall {
	var contentCategoryIds_ []string
	for _, v := range contentCategoryIds {
		contentCategoryIds_ = append(contentCategoryIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("contentCategoryIds", contentCategoryIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only placement groups that are associated with these directory
// sites.
func (c *PlacementGroupsListCall) DirectorySiteIds(directorySiteIds ...int64) *PlacementGroupsListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only placement groups
// with these IDs.
func (c *PlacementGroupsListCall) Ids(ids ...int64) *PlacementGroupsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementGroupsListCall) MaxResults(maxResults int64) *PlacementGroupsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementGroupsListCall) PageToken(pageToken string) *PlacementGroupsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PlacementGroupType sets the optional parameter "placementGroupType":
// Select only placement groups belonging with this group type. A
// package is a simple group of placements that acts as a single pricing
// point for a group of tags. A roadblock is a group of placements that
// not only acts as a single pricing point but also assumes that all the
// tags in it will be served at the same time. A roadblock requires one
// of its assigned placements to be marked as primary for reporting.
//
// Possible values:
//   "PLACEMENT_PACKAGE"
//   "PLACEMENT_ROADBLOCK"
func (c *PlacementGroupsListCall) PlacementGroupType(placementGroupType string) *PlacementGroupsListCall {
	c.urlParams_.Set("placementGroupType", placementGroupType)
	return c
}

// PlacementStrategyIds sets the optional parameter
// "placementStrategyIds": Select only placement groups that are
// associated with these placement strategies.
func (c *PlacementGroupsListCall) PlacementStrategyIds(placementStrategyIds ...int64) *PlacementGroupsListCall {
	var placementStrategyIds_ []string
	for _, v := range placementStrategyIds {
		placementStrategyIds_ = append(placementStrategyIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementStrategyIds", placementStrategyIds_)
	return c
}

// PricingTypes sets the optional parameter "pricingTypes": Select only
// placement groups with these pricing types.
//
// Possible values:
//   "PRICING_TYPE_CPA"
//   "PRICING_TYPE_CPC"
//   "PRICING_TYPE_CPM"
//   "PRICING_TYPE_FLAT_RATE_CLICKS"
//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
func (c *PlacementGroupsListCall) PricingTypes(pricingTypes ...string) *PlacementGroupsListCall {
	c.urlParams_.SetMulti("pricingTypes", append([]string{}, pricingTypes...))
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for placement groups by name or ID. Wildcards (*) are
// allowed. For example, "placement*2015" will return placement groups
// with names like "placement group June 2015", "placement group May
// 2015", or simply "placements 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "placementgroup" will match placement
// groups with name "my placementgroup", "placementgroup 2015", or
// simply "placementgroup".
func (c *PlacementGroupsListCall) SearchString(searchString string) *PlacementGroupsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteIds sets the optional parameter "siteIds": Select only placement
// groups that are associated with these sites.
func (c *PlacementGroupsListCall) SiteIds(siteIds ...int64) *PlacementGroupsListCall {
	var siteIds_ []string
	for _, v := range siteIds {
		siteIds_ = append(siteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteIds", siteIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *PlacementGroupsListCall) SortField(sortField string) *PlacementGroupsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *PlacementGroupsListCall) SortOrder(sortOrder string) *PlacementGroupsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsListCall) Fields(s ...googleapi.Field) *PlacementGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementGroupsListCall) IfNoneMatch(entityTag string) *PlacementGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementGroupsListCall) Context(ctx context.Context) *PlacementGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.list" call.
// Exactly one of *PlacementGroupsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *PlacementGroupsListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsListCall) Do(opts ...googleapi.CallOption) (*PlacementGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement groups, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only placement groups that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived placements. Don't set this field to select both archived and non-archived placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only placement groups that belong to these campaigns.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentCategoryIds": {
	//       "description": "Select only placement groups that are associated with these content categories.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only placement groups that are associated with these directory sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only placement groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementGroupType": {
	//       "description": "Select only placement groups belonging with this group type. A package is a simple group of placements that acts as a single pricing point for a group of tags. A roadblock is a group of placements that not only acts as a single pricing point but also assumes that all the tags in it will be served at the same time. A roadblock requires one of its assigned placements to be marked as primary for reporting.",
	//       "enum": [
	//         "PLACEMENT_PACKAGE",
	//         "PLACEMENT_ROADBLOCK"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementStrategyIds": {
	//       "description": "Select only placement groups that are associated with these placement strategies.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pricingTypes": {
	//       "description": "Select only placement groups with these pricing types.",
	//       "enum": [
	//         "PRICING_TYPE_CPA",
	//         "PRICING_TYPE_CPC",
	//         "PRICING_TYPE_CPM",
	//         "PRICING_TYPE_FLAT_RATE_CLICKS",
	//         "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for placement groups by name or ID. Wildcards (*) are allowed. For example, \"placement*2015\" will return placement groups with names like \"placement group June 2015\", \"placement group May 2015\", or simply \"placements 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placementgroup\" will match placement groups with name \"my placementgroup\", \"placementgroup 2015\", or simply \"placementgroup\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteIds": {
	//       "description": "Select only placement groups that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "response": {
	//     "$ref": "PlacementGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *PlacementGroupsListCall) Pages(ctx context.Context, f func(*PlacementGroupsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.placementGroups.patch":

type PlacementGroupsPatchCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
}

// Patch: Updates an existing placement group. This method supports
// patch semantics.
func (r *PlacementGroupsService) Patch(profileId int64, id int64, placementgroup *PlacementGroup) *PlacementGroupsPatchCall {
	c := &PlacementGroupsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.placementgroup = placementgroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsPatchCall) Fields(s ...googleapi.Field) *PlacementGroupsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementGroupsPatchCall) Context(ctx context.Context) *PlacementGroupsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.patch" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsPatchCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement group. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placementGroups.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement group ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementGroups.update":

type PlacementGroupsUpdateCall struct {
	s              *Service
	profileId      int64
	placementgroup *PlacementGroup
	urlParams_     gensupport.URLParams
	ctx_           context.Context
}

// Update: Updates an existing placement group.
func (r *PlacementGroupsService) Update(profileId int64, placementgroup *PlacementGroup) *PlacementGroupsUpdateCall {
	c := &PlacementGroupsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementgroup = placementgroup
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementGroupsUpdateCall) Fields(s ...googleapi.Field) *PlacementGroupsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementGroupsUpdateCall) Context(ctx context.Context) *PlacementGroupsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementgroup)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementGroups.update" call.
// Exactly one of *PlacementGroup or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlacementGroup.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementGroupsUpdateCall) Do(opts ...googleapi.CallOption) (*PlacementGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement group.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placementGroups.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementGroups",
	//   "request": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "response": {
	//     "$ref": "PlacementGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.delete":

type PlacementStrategiesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing placement strategy.
func (r *PlacementStrategiesService) Delete(profileId int64, id int64) *PlacementStrategiesDeleteCall {
	c := &PlacementStrategiesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesDeleteCall) Fields(s ...googleapi.Field) *PlacementStrategiesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesDeleteCall) Context(ctx context.Context) *PlacementStrategiesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.delete" call.
func (c *PlacementStrategiesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing placement strategy.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.placementStrategies.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement strategy ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.get":

type PlacementStrategiesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one placement strategy by ID.
func (r *PlacementStrategiesService) Get(profileId int64, id int64) *PlacementStrategiesGetCall {
	c := &PlacementStrategiesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesGetCall) Fields(s ...googleapi.Field) *PlacementStrategiesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementStrategiesGetCall) IfNoneMatch(entityTag string) *PlacementStrategiesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesGetCall) Context(ctx context.Context) *PlacementStrategiesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.get" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesGetCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one placement strategy by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementStrategies.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement strategy ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies/{id}",
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.insert":

type PlacementStrategiesInsertCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
}

// Insert: Inserts a new placement strategy.
func (r *PlacementStrategiesService) Insert(profileId int64, placementstrategy *PlacementStrategy) *PlacementStrategiesInsertCall {
	c := &PlacementStrategiesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementstrategy = placementstrategy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesInsertCall) Fields(s ...googleapi.Field) *PlacementStrategiesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesInsertCall) Context(ctx context.Context) *PlacementStrategiesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementstrategy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.insert" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesInsertCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement strategy.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placementStrategies.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.list":

type PlacementStrategiesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of placement strategies, possibly filtered.
func (r *PlacementStrategiesService) List(profileId int64) *PlacementStrategiesListCall {
	c := &PlacementStrategiesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only placement
// strategies with these IDs.
func (c *PlacementStrategiesListCall) Ids(ids ...int64) *PlacementStrategiesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementStrategiesListCall) MaxResults(maxResults int64) *PlacementStrategiesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementStrategiesListCall) PageToken(pageToken string) *PlacementStrategiesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "placementstrategy*2015" will return objects with names like
// "placementstrategy June 2015", "placementstrategy April 2015", or
// simply "placementstrategy 2015". Most of the searches also add
// wildcards implicitly at the start and the end of the search string.
// For example, a search string of "placementstrategy" will match
// objects with name "my placementstrategy", "placementstrategy 2015",
// or simply "placementstrategy".
func (c *PlacementStrategiesListCall) SearchString(searchString string) *PlacementStrategiesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *PlacementStrategiesListCall) SortField(sortField string) *PlacementStrategiesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *PlacementStrategiesListCall) SortOrder(sortOrder string) *PlacementStrategiesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesListCall) Fields(s ...googleapi.Field) *PlacementStrategiesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementStrategiesListCall) IfNoneMatch(entityTag string) *PlacementStrategiesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesListCall) Context(ctx context.Context) *PlacementStrategiesListCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.list" call.
// Exactly one of *PlacementStrategiesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *PlacementStrategiesListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesListCall) Do(opts ...googleapi.CallOption) (*PlacementStrategiesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategiesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement strategies, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placementStrategies.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only placement strategies with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"placementstrategy*2015\" will return objects with names like \"placementstrategy June 2015\", \"placementstrategy April 2015\", or simply \"placementstrategy 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placementstrategy\" will match objects with name \"my placementstrategy\", \"placementstrategy 2015\", or simply \"placementstrategy\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "response": {
	//     "$ref": "PlacementStrategiesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *PlacementStrategiesListCall) Pages(ctx context.Context, f func(*PlacementStrategiesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.placementStrategies.patch":

type PlacementStrategiesPatchCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
}

// Patch: Updates an existing placement strategy. This method supports
// patch semantics.
func (r *PlacementStrategiesService) Patch(profileId int64, id int64, placementstrategy *PlacementStrategy) *PlacementStrategiesPatchCall {
	c := &PlacementStrategiesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.placementstrategy = placementstrategy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesPatchCall) Fields(s ...googleapi.Field) *PlacementStrategiesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesPatchCall) Context(ctx context.Context) *PlacementStrategiesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementstrategy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.patch" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesPatchCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement strategy. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placementStrategies.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement strategy ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placementStrategies.update":

type PlacementStrategiesUpdateCall struct {
	s                 *Service
	profileId         int64
	placementstrategy *PlacementStrategy
	urlParams_        gensupport.URLParams
	ctx_              context.Context
}

// Update: Updates an existing placement strategy.
func (r *PlacementStrategiesService) Update(profileId int64, placementstrategy *PlacementStrategy) *PlacementStrategiesUpdateCall {
	c := &PlacementStrategiesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placementstrategy = placementstrategy
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementStrategiesUpdateCall) Fields(s ...googleapi.Field) *PlacementStrategiesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementStrategiesUpdateCall) Context(ctx context.Context) *PlacementStrategiesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementStrategiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placementstrategy)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placementStrategies")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placementStrategies.update" call.
// Exactly one of *PlacementStrategy or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementStrategy.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementStrategiesUpdateCall) Do(opts ...googleapi.CallOption) (*PlacementStrategy, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementStrategy{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement strategy.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placementStrategies.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placementStrategies",
	//   "request": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "response": {
	//     "$ref": "PlacementStrategy"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.generatetags":

type PlacementsGeneratetagsCall struct {
	s          *Service
	profileId  int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Generatetags: Generates tags for a placement.
func (r *PlacementsService) Generatetags(profileId int64) *PlacementsGeneratetagsCall {
	c := &PlacementsGeneratetagsCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// CampaignId sets the optional parameter "campaignId": Generate
// placements belonging to this campaign. This is a required field.
func (c *PlacementsGeneratetagsCall) CampaignId(campaignId int64) *PlacementsGeneratetagsCall {
	c.urlParams_.Set("campaignId", fmt.Sprint(campaignId))
	return c
}

// PlacementIds sets the optional parameter "placementIds": Generate
// tags for these placements.
func (c *PlacementsGeneratetagsCall) PlacementIds(placementIds ...int64) *PlacementsGeneratetagsCall {
	var placementIds_ []string
	for _, v := range placementIds {
		placementIds_ = append(placementIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementIds", placementIds_)
	return c
}

// TagFormats sets the optional parameter "tagFormats": Tag formats to
// generate for these placements.
//
// Possible values:
//   "PLACEMENT_TAG_CLICK_COMMANDS"
//   "PLACEMENT_TAG_IFRAME_ILAYER"
//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT"
//   "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH"
//   "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3"
//   "PLACEMENT_TAG_INTERNAL_REDIRECT"
//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT"
//   "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT"
//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT"
//   "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_JAVASCRIPT"
//   "PLACEMENT_TAG_JAVASCRIPT_LEGACY"
//   "PLACEMENT_TAG_STANDARD"
//   "PLACEMENT_TAG_TRACKING"
//   "PLACEMENT_TAG_TRACKING_IFRAME"
//   "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
func (c *PlacementsGeneratetagsCall) TagFormats(tagFormats ...string) *PlacementsGeneratetagsCall {
	c.urlParams_.SetMulti("tagFormats", append([]string{}, tagFormats...))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsGeneratetagsCall) Fields(s ...googleapi.Field) *PlacementsGeneratetagsCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsGeneratetagsCall) Context(ctx context.Context) *PlacementsGeneratetagsCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsGeneratetagsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements/generatetags")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.generatetags" call.
// Exactly one of *PlacementsGenerateTagsResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *PlacementsGenerateTagsResponse.ServerResponse.Header or (if a
// response was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementsGeneratetagsCall) Do(opts ...googleapi.CallOption) (*PlacementsGenerateTagsResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementsGenerateTagsResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Generates tags for a placement.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placements.generatetags",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "campaignId": {
	//       "description": "Generate placements belonging to this campaign. This is a required field.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementIds": {
	//       "description": "Generate tags for these placements.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "tagFormats": {
	//       "description": "Tag formats to generate for these placements.",
	//       "enum": [
	//         "PLACEMENT_TAG_CLICK_COMMANDS",
	//         "PLACEMENT_TAG_IFRAME_ILAYER",
	//         "PLACEMENT_TAG_IFRAME_JAVASCRIPT",
	//         "PLACEMENT_TAG_IFRAME_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH",
	//         "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_3",
	//         "PLACEMENT_TAG_INTERNAL_REDIRECT",
	//         "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT",
	//         "PLACEMENT_TAG_INTERSTITIAL_IFRAME_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_INTERSTITIAL_INTERNAL_REDIRECT",
	//         "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT",
	//         "PLACEMENT_TAG_INTERSTITIAL_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_JAVASCRIPT",
	//         "PLACEMENT_TAG_JAVASCRIPT_LEGACY",
	//         "PLACEMENT_TAG_STANDARD",
	//         "PLACEMENT_TAG_TRACKING",
	//         "PLACEMENT_TAG_TRACKING_IFRAME",
	//         "PLACEMENT_TAG_TRACKING_JAVASCRIPT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements/generatetags",
	//   "response": {
	//     "$ref": "PlacementsGenerateTagsResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.get":

type PlacementsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one placement by ID.
func (r *PlacementsService) Get(profileId int64, id int64) *PlacementsGetCall {
	c := &PlacementsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsGetCall) Fields(s ...googleapi.Field) *PlacementsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementsGetCall) IfNoneMatch(entityTag string) *PlacementsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsGetCall) Context(ctx context.Context) *PlacementsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.get" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsGetCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one placement by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placements.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements/{id}",
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.insert":

type PlacementsInsertCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new placement.
func (r *PlacementsService) Insert(profileId int64, placement *Placement) *PlacementsInsertCall {
	c := &PlacementsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placement = placement
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsInsertCall) Fields(s ...googleapi.Field) *PlacementsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsInsertCall) Context(ctx context.Context) *PlacementsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placement)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.insert" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsInsertCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new placement.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.placements.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.list":

type PlacementsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of placements, possibly filtered.
func (r *PlacementsService) List(profileId int64) *PlacementsListCall {
	c := &PlacementsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only placements that belong to these advertisers.
func (c *PlacementsListCall) AdvertiserIds(advertiserIds ...int64) *PlacementsListCall {
	var advertiserIds_ []string
	for _, v := range advertiserIds {
		advertiserIds_ = append(advertiserIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("advertiserIds", advertiserIds_)
	return c
}

// Archived sets the optional parameter "archived": Select only archived
// placements. Don't set this field to select both archived and
// non-archived placements.
func (c *PlacementsListCall) Archived(archived bool) *PlacementsListCall {
	c.urlParams_.Set("archived", fmt.Sprint(archived))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// placements that belong to these campaigns.
func (c *PlacementsListCall) CampaignIds(campaignIds ...int64) *PlacementsListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// Compatibilities sets the optional parameter "compatibilities": Select
// only placements that are associated with these compatibilities. WEB
// and WEB_INTERSTITIAL refer to rendering either on desktop or on
// mobile devices for regular or interstitial ads respectively. APP and
// APP_INTERSTITIAL are for rendering in mobile apps. IN_STREAM_VIDEO
// refers to rendering in in-stream video ads developed with the VAST
// standard.
//
// Possible values:
//   "APP"
//   "APP_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
//   "WEB"
//   "WEB_INTERSTITIAL"
func (c *PlacementsListCall) Compatibilities(compatibilities ...string) *PlacementsListCall {
	c.urlParams_.SetMulti("compatibilities", append([]string{}, compatibilities...))
	return c
}

// ContentCategoryIds sets the optional parameter "contentCategoryIds":
// Select only placements that are associated with these content
// categories.
func (c *PlacementsListCall) ContentCategoryIds(contentCategoryIds ...int64) *PlacementsListCall {
	var contentCategoryIds_ []string
	for _, v := range contentCategoryIds {
		contentCategoryIds_ = append(contentCategoryIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("contentCategoryIds", contentCategoryIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only placements that are associated with these directory
// sites.
func (c *PlacementsListCall) DirectorySiteIds(directorySiteIds ...int64) *PlacementsListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// GroupIds sets the optional parameter "groupIds": Select only
// placements that belong to these placement groups.
func (c *PlacementsListCall) GroupIds(groupIds ...int64) *PlacementsListCall {
	var groupIds_ []string
	for _, v := range groupIds {
		groupIds_ = append(groupIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("groupIds", groupIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only placements with
// these IDs.
func (c *PlacementsListCall) Ids(ids ...int64) *PlacementsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *PlacementsListCall) MaxResults(maxResults int64) *PlacementsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *PlacementsListCall) PageToken(pageToken string) *PlacementsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// PaymentSource sets the optional parameter "paymentSource": Select
// only placements with this payment source.
//
// Possible values:
//   "PLACEMENT_AGENCY_PAID"
//   "PLACEMENT_PUBLISHER_PAID"
func (c *PlacementsListCall) PaymentSource(paymentSource string) *PlacementsListCall {
	c.urlParams_.Set("paymentSource", paymentSource)
	return c
}

// PlacementStrategyIds sets the optional parameter
// "placementStrategyIds": Select only placements that are associated
// with these placement strategies.
func (c *PlacementsListCall) PlacementStrategyIds(placementStrategyIds ...int64) *PlacementsListCall {
	var placementStrategyIds_ []string
	for _, v := range placementStrategyIds {
		placementStrategyIds_ = append(placementStrategyIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("placementStrategyIds", placementStrategyIds_)
	return c
}

// PricingTypes sets the optional parameter "pricingTypes": Select only
// placements with these pricing types.
//
// Possible values:
//   "PRICING_TYPE_CPA"
//   "PRICING_TYPE_CPC"
//   "PRICING_TYPE_CPM"
//   "PRICING_TYPE_FLAT_RATE_CLICKS"
//   "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
func (c *PlacementsListCall) PricingTypes(pricingTypes ...string) *PlacementsListCall {
	c.urlParams_.SetMulti("pricingTypes", append([]string{}, pricingTypes...))
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for placements by name or ID. Wildcards (*) are allowed.
// For example, "placement*2015" will return placements with names like
// "placement June 2015", "placement May 2015", or simply "placements
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "placement" will match placements with name "my placement",
// "placement 2015", or simply "placement".
func (c *PlacementsListCall) SearchString(searchString string) *PlacementsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteIds sets the optional parameter "siteIds": Select only placements
// that are associated with these sites.
func (c *PlacementsListCall) SiteIds(siteIds ...int64) *PlacementsListCall {
	var siteIds_ []string
	for _, v := range siteIds {
		siteIds_ = append(siteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteIds", siteIds_)
	return c
}

// SizeIds sets the optional parameter "sizeIds": Select only placements
// that are associated with these sizes.
func (c *PlacementsListCall) SizeIds(sizeIds ...int64) *PlacementsListCall {
	var sizeIds_ []string
	for _, v := range sizeIds {
		sizeIds_ = append(sizeIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("sizeIds", sizeIds_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *PlacementsListCall) SortField(sortField string) *PlacementsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *PlacementsListCall) SortOrder(sortOrder string) *PlacementsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsListCall) Fields(s ...googleapi.Field) *PlacementsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlacementsListCall) IfNoneMatch(entityTag string) *PlacementsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsListCall) Context(ctx context.Context) *PlacementsListCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.list" call.
// Exactly one of *PlacementsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PlacementsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlacementsListCall) Do(opts ...googleapi.CallOption) (*PlacementsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlacementsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placements, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.placements.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only placements that belong to these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "archived": {
	//       "description": "Select only archived placements. Don't set this field to select both archived and non-archived placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only placements that belong to these campaigns.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "compatibilities": {
	//       "description": "Select only placements that are associated with these compatibilities. WEB and WEB_INTERSTITIAL refer to rendering either on desktop or on mobile devices for regular or interstitial ads respectively. APP and APP_INTERSTITIAL are for rendering in mobile apps. IN_STREAM_VIDEO refers to rendering in in-stream video ads developed with the VAST standard.",
	//       "enum": [
	//         "APP",
	//         "APP_INTERSTITIAL",
	//         "IN_STREAM_VIDEO",
	//         "WEB",
	//         "WEB_INTERSTITIAL"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "contentCategoryIds": {
	//       "description": "Select only placements that are associated with these content categories.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only placements that are associated with these directory sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "groupIds": {
	//       "description": "Select only placements that belong to these placement groups.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only placements with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "paymentSource": {
	//       "description": "Select only placements with this payment source.",
	//       "enum": [
	//         "PLACEMENT_AGENCY_PAID",
	//         "PLACEMENT_PUBLISHER_PAID"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "placementStrategyIds": {
	//       "description": "Select only placements that are associated with these placement strategies.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "pricingTypes": {
	//       "description": "Select only placements with these pricing types.",
	//       "enum": [
	//         "PRICING_TYPE_CPA",
	//         "PRICING_TYPE_CPC",
	//         "PRICING_TYPE_CPM",
	//         "PRICING_TYPE_FLAT_RATE_CLICKS",
	//         "PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for placements by name or ID. Wildcards (*) are allowed. For example, \"placement*2015\" will return placements with names like \"placement June 2015\", \"placement May 2015\", or simply \"placements 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"placement\" will match placements with name \"my placement\", \"placement 2015\", or simply \"placement\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteIds": {
	//       "description": "Select only placements that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sizeIds": {
	//       "description": "Select only placements that are associated with these sizes.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "response": {
	//     "$ref": "PlacementsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *PlacementsListCall) Pages(ctx context.Context, f func(*PlacementsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.placements.patch":

type PlacementsPatchCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing placement. This method supports patch
// semantics.
func (r *PlacementsService) Patch(profileId int64, id int64, placement *Placement) *PlacementsPatchCall {
	c := &PlacementsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.placement = placement
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsPatchCall) Fields(s ...googleapi.Field) *PlacementsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsPatchCall) Context(ctx context.Context) *PlacementsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placement)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.patch" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsPatchCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.placements.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Placement ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.placements.update":

type PlacementsUpdateCall struct {
	s          *Service
	profileId  int64
	placement  *Placement
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing placement.
func (r *PlacementsService) Update(profileId int64, placement *Placement) *PlacementsUpdateCall {
	c := &PlacementsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.placement = placement
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlacementsUpdateCall) Fields(s ...googleapi.Field) *PlacementsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlacementsUpdateCall) Context(ctx context.Context) *PlacementsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *PlacementsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.placement)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/placements")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.placements.update" call.
// Exactly one of *Placement or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Placement.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *PlacementsUpdateCall) Do(opts ...googleapi.CallOption) (*Placement, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Placement{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing placement.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.placements.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/placements",
	//   "request": {
	//     "$ref": "Placement"
	//   },
	//   "response": {
	//     "$ref": "Placement"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.platformTypes.list":

type PlatformTypesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of platform types.
func (r *PlatformTypesService) List(profileId int64) *PlatformTypesListCall {
	c := &PlatformTypesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PlatformTypesListCall) Fields(s ...googleapi.Field) *PlatformTypesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PlatformTypesListCall) IfNoneMatch(entityTag string) *PlatformTypesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PlatformTypesListCall) Context(ctx context.Context) *PlatformTypesListCall {
	c.ctx_ = ctx
	return c
}

func (c *PlatformTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/platformTypes")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.platformTypes.list" call.
// Exactly one of *PlatformTypesListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *PlatformTypesListResponse.ServerResponse.Header or (if a response
// was returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PlatformTypesListCall) Do(opts ...googleapi.CallOption) (*PlatformTypesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PlatformTypesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of platform types.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.platformTypes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/platformTypes",
	//   "response": {
	//     "$ref": "PlatformTypesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.postalCodes.list":

type PostalCodesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of postal codes.
func (r *PostalCodesService) List(profileId int64) *PostalCodesListCall {
	c := &PostalCodesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *PostalCodesListCall) Fields(s ...googleapi.Field) *PostalCodesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *PostalCodesListCall) IfNoneMatch(entityTag string) *PostalCodesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *PostalCodesListCall) Context(ctx context.Context) *PostalCodesListCall {
	c.ctx_ = ctx
	return c
}

func (c *PostalCodesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/postalCodes")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.postalCodes.list" call.
// Exactly one of *PostalCodesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *PostalCodesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *PostalCodesListCall) Do(opts ...googleapi.CallOption) (*PostalCodesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &PostalCodesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of postal codes.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.postalCodes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/postalCodes",
	//   "response": {
	//     "$ref": "PostalCodesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.regions.list":

type RegionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of regions.
func (r *RegionsService) List(profileId int64) *RegionsListCall {
	c := &RegionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *RegionsListCall) Fields(s ...googleapi.Field) *RegionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *RegionsListCall) IfNoneMatch(entityTag string) *RegionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *RegionsListCall) Context(ctx context.Context) *RegionsListCall {
	c.ctx_ = ctx
	return c
}

func (c *RegionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/regions")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.regions.list" call.
// Exactly one of *RegionsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RegionsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *RegionsListCall) Do(opts ...googleapi.CallOption) (*RegionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &RegionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of regions.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.regions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/regions",
	//   "response": {
	//     "$ref": "RegionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.reports.delete":

type ReportsDeleteCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes a report by its ID.
func (r *ReportsService) Delete(profileId int64, reportId int64) *ReportsDeleteCall {
	c := &ReportsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsDeleteCall) Fields(s ...googleapi.Field) *ReportsDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsDeleteCall) Context(ctx context.Context) *ReportsDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.delete" call.
func (c *ReportsDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes a report by its ID.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.reports.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.get":

type ReportsGetCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Retrieves a report by its ID.
func (r *ReportsService) Get(profileId int64, reportId int64) *ReportsGetCall {
	c := &ReportsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsGetCall) Fields(s ...googleapi.Field) *ReportsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReportsGetCall) IfNoneMatch(entityTag string) *ReportsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsGetCall) Context(ctx context.Context) *ReportsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.get" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsGetCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report by its ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.insert":

type ReportsInsertCall struct {
	s          *Service
	profileId  int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Creates a report.
func (r *ReportsService) Insert(profileId int64, report *Report) *ReportsInsertCall {
	c := &ReportsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsInsertCall) Fields(s ...googleapi.Field) *ReportsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsInsertCall) Context(ctx context.Context) *ReportsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.report)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.insert" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsInsertCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Creates a report.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.list":

type ReportsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves list of reports.
func (r *ReportsService) List(profileId int64) *ReportsListCall {
	c := &ReportsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ReportsListCall) MaxResults(maxResults int64) *ReportsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *ReportsListCall) PageToken(pageToken string) *ReportsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// Scope sets the optional parameter "scope": The scope that defines
// which results are returned, default is 'MINE'.
//
// Possible values:
//   "ALL" - All reports in account.
//   "MINE" (default) - My reports.
func (c *ReportsListCall) Scope(scope string) *ReportsListCall {
	c.urlParams_.Set("scope", scope)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID" - Sort by report ID.
//   "LAST_MODIFIED_TIME" (default) - Sort by 'lastModifiedTime' field.
//   "NAME" - Sort by name of reports.
func (c *ReportsListCall) SortField(sortField string) *ReportsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is 'DESCENDING'.
//
// Possible values:
//   "ASCENDING" - Ascending order.
//   "DESCENDING" (default) - Descending order.
func (c *ReportsListCall) SortOrder(sortOrder string) *ReportsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsListCall) Fields(s ...googleapi.Field) *ReportsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReportsListCall) IfNoneMatch(entityTag string) *ReportsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsListCall) Context(ctx context.Context) *ReportsListCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.list" call.
// Exactly one of *ReportList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ReportList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReportsListCall) Do(opts ...googleapi.CallOption) (*ReportList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &ReportList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of reports.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "scope": {
	//       "default": "MINE",
	//       "description": "The scope that defines which results are returned, default is 'MINE'.",
	//       "enum": [
	//         "ALL",
	//         "MINE"
	//       ],
	//       "enumDescriptions": [
	//         "All reports in account.",
	//         "My reports."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "Sort by report ID.",
	//         "Sort by 'lastModifiedTime' field.",
	//         "Sort by name of reports."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results, default is 'DESCENDING'.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "Ascending order.",
	//         "Descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports",
	//   "response": {
	//     "$ref": "ReportList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ReportsListCall) Pages(ctx context.Context, f func(*ReportList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.reports.patch":

type ReportsPatchCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates a report. This method supports patch semantics.
func (r *ReportsService) Patch(profileId int64, reportId int64, report *Report) *ReportsPatchCall {
	c := &ReportsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsPatchCall) Fields(s ...googleapi.Field) *ReportsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsPatchCall) Context(ctx context.Context) *ReportsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.report)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.patch" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsPatchCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a report. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.reports.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.run":

type ReportsRunCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Run: Runs a report.
func (r *ReportsService) Run(profileId int64, reportId int64) *ReportsRunCall {
	c := &ReportsRunCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// Synchronous sets the optional parameter "synchronous": If set and
// true, tries to run the report synchronously.
func (c *ReportsRunCall) Synchronous(synchronous bool) *ReportsRunCall {
	c.urlParams_.Set("synchronous", fmt.Sprint(synchronous))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsRunCall) Fields(s ...googleapi.Field) *ReportsRunCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsRunCall) Context(ctx context.Context) *ReportsRunCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsRunCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}/run")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.run" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ReportsRunCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Runs a report.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.run",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "synchronous": {
	//       "description": "If set and true, tries to run the report synchronously.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/run",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.update":

type ReportsUpdateCall struct {
	s          *Service
	profileId  int64
	reportId   int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates a report.
func (r *ReportsService) Update(profileId int64, reportId int64, report *Report) *ReportsUpdateCall {
	c := &ReportsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsUpdateCall) Fields(s ...googleapi.Field) *ReportsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsUpdateCall) Context(ctx context.Context) *ReportsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.report)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.update" call.
// Exactly one of *Report or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Report.ServerResponse.Header or (if a response was returned at all)
// in error.(*googleapi.Error).Header. Use googleapi.IsNotModified to
// check whether the returned error was because http.StatusNotModified
// was returned.
func (c *ReportsUpdateCall) Do(opts ...googleapi.CallOption) (*Report, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Report{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates a report.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.reports.update",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "Report"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.compatibleFields.query":

type ReportsCompatibleFieldsQueryCall struct {
	s          *Service
	profileId  int64
	report     *Report
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Query: Returns the fields that are compatible to be selected in the
// respective sections of a report criteria, given the fields already
// selected in the input report and user permissions.
func (r *ReportsCompatibleFieldsService) Query(profileId int64, report *Report) *ReportsCompatibleFieldsQueryCall {
	c := &ReportsCompatibleFieldsQueryCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.report = report
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsCompatibleFieldsQueryCall) Fields(s ...googleapi.Field) *ReportsCompatibleFieldsQueryCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsCompatibleFieldsQueryCall) Context(ctx context.Context) *ReportsCompatibleFieldsQueryCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsCompatibleFieldsQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.report)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/compatiblefields/query")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.compatibleFields.query" call.
// Exactly one of *CompatibleFields or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *CompatibleFields.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *ReportsCompatibleFieldsQueryCall) Do(opts ...googleapi.CallOption) (*CompatibleFields, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &CompatibleFields{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Returns the fields that are compatible to be selected in the respective sections of a report criteria, given the fields already selected in the input report and user permissions.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.reports.compatibleFields.query",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The DFA user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/compatiblefields/query",
	//   "request": {
	//     "$ref": "Report"
	//   },
	//   "response": {
	//     "$ref": "CompatibleFields"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// method id "dfareporting.reports.files.get":

type ReportsFilesGetCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	fileId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Retrieves a report file.
func (r *ReportsFilesService) Get(profileId int64, reportId int64, fileId int64) *ReportsFilesGetCall {
	c := &ReportsFilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	c.fileId = fileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsFilesGetCall) Fields(s ...googleapi.Field) *ReportsFilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReportsFilesGetCall) IfNoneMatch(entityTag string) *ReportsFilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do and Download
// methods. Any pending HTTP request will be aborted if the provided
// context is canceled.
func (c *ReportsFilesGetCall) Context(ctx context.Context) *ReportsFilesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsFilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}/files/{fileId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
		"fileId":    strconv.FormatInt(c.fileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Download fetches the API endpoint's "media" value, instead of the normal
// API response value. If the returned error is nil, the Response is guaranteed to
// have a 2xx status code. Callers must close the Response.Body as usual.
func (c *ReportsFilesGetCall) Download(opts ...googleapi.CallOption) (*http.Response, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("media")
	if err != nil {
		return nil, err
	}
	if err := googleapi.CheckMediaResponse(res); err != nil {
		res.Body.Close()
		return nil, err
	}
	return res, nil
}

// Do executes the "dfareporting.reports.files.get" call.
// Exactly one of *File or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *File.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *ReportsFilesGetCall) Do(opts ...googleapi.CallOption) (*File, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &File{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.files.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId",
	//     "fileId"
	//   ],
	//   "parameters": {
	//     "fileId": {
	//       "description": "The ID of the report file.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/files/{fileId}",
	//   "response": {
	//     "$ref": "File"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ],
	//   "supportsMediaDownload": true
	// }

}

// method id "dfareporting.reports.files.list":

type ReportsFilesListCall struct {
	s            *Service
	profileId    int64
	reportId     int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Lists files for a report.
func (r *ReportsFilesService) List(profileId int64, reportId int64) *ReportsFilesListCall {
	c := &ReportsFilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.reportId = reportId
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *ReportsFilesListCall) MaxResults(maxResults int64) *ReportsFilesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": The value of the
// nextToken from the previous result page.
func (c *ReportsFilesListCall) PageToken(pageToken string) *ReportsFilesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": The field by which
// to sort the list.
//
// Possible values:
//   "ID" - Sort by file ID.
//   "LAST_MODIFIED_TIME" (default) - Sort by 'lastmodifiedAt' field.
func (c *ReportsFilesListCall) SortField(sortField string) *ReportsFilesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is 'DESCENDING'.
//
// Possible values:
//   "ASCENDING" - Ascending order.
//   "DESCENDING" (default) - Descending order.
func (c *ReportsFilesListCall) SortOrder(sortOrder string) *ReportsFilesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *ReportsFilesListCall) Fields(s ...googleapi.Field) *ReportsFilesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *ReportsFilesListCall) IfNoneMatch(entityTag string) *ReportsFilesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *ReportsFilesListCall) Context(ctx context.Context) *ReportsFilesListCall {
	c.ctx_ = ctx
	return c
}

func (c *ReportsFilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/reports/{reportId}/files")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"reportId":  strconv.FormatInt(c.reportId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.reports.files.list" call.
// Exactly one of *FileList or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *FileList.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *ReportsFilesListCall) Do(opts ...googleapi.CallOption) (*FileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &FileList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists files for a report.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.files.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "reportId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "10",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "The value of the nextToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "The DFA profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "reportId": {
	//       "description": "The ID of the parent report.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "LAST_MODIFIED_TIME",
	//       "description": "The field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "LAST_MODIFIED_TIME"
	//       ],
	//       "enumDescriptions": [
	//         "Sort by file ID.",
	//         "Sort by 'lastmodifiedAt' field."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "DESCENDING",
	//       "description": "Order of sorted results, default is 'DESCENDING'.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "Ascending order.",
	//         "Descending order."
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/reports/{reportId}/files",
	//   "response": {
	//     "$ref": "FileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *ReportsFilesListCall) Pages(ctx context.Context, f func(*FileList) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.sites.get":

type SitesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one site by ID.
func (r *SitesService) Get(profileId int64, id int64) *SitesGetCall {
	c := &SitesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesGetCall) Fields(s ...googleapi.Field) *SitesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SitesGetCall) IfNoneMatch(entityTag string) *SitesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SitesGetCall) Context(ctx context.Context) *SitesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *SitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sites/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.get" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SitesGetCall) Do(opts ...googleapi.CallOption) (*Site, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Site{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one site by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sites.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Site ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites/{id}",
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.insert":

type SitesInsertCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new site.
func (r *SitesService) Insert(profileId int64, site *Site) *SitesInsertCall {
	c := &SitesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.site = site
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesInsertCall) Fields(s ...googleapi.Field) *SitesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SitesInsertCall) Context(ctx context.Context) *SitesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *SitesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.site)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sites")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.insert" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SitesInsertCall) Do(opts ...googleapi.CallOption) (*Site, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Site{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new site.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.sites.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.list":

type SitesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of sites, possibly filtered.
func (r *SitesService) List(profileId int64) *SitesListCall {
	c := &SitesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AcceptsInStreamVideoPlacements sets the optional parameter
// "acceptsInStreamVideoPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *SitesListCall) AcceptsInStreamVideoPlacements(acceptsInStreamVideoPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsInStreamVideoPlacements", fmt.Sprint(acceptsInStreamVideoPlacements))
	return c
}

// AcceptsInterstitialPlacements sets the optional parameter
// "acceptsInterstitialPlacements": This search filter is no longer
// supported and will have no effect on the results returned.
func (c *SitesListCall) AcceptsInterstitialPlacements(acceptsInterstitialPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsInterstitialPlacements", fmt.Sprint(acceptsInterstitialPlacements))
	return c
}

// AcceptsPublisherPaidPlacements sets the optional parameter
// "acceptsPublisherPaidPlacements": Select only sites that accept
// publisher paid placements.
func (c *SitesListCall) AcceptsPublisherPaidPlacements(acceptsPublisherPaidPlacements bool) *SitesListCall {
	c.urlParams_.Set("acceptsPublisherPaidPlacements", fmt.Sprint(acceptsPublisherPaidPlacements))
	return c
}

// AdWordsSite sets the optional parameter "adWordsSite": Select only
// AdWords sites.
func (c *SitesListCall) AdWordsSite(adWordsSite bool) *SitesListCall {
	c.urlParams_.Set("adWordsSite", fmt.Sprint(adWordsSite))
	return c
}

// Approved sets the optional parameter "approved": Select only approved
// sites.
func (c *SitesListCall) Approved(approved bool) *SitesListCall {
	c.urlParams_.Set("approved", fmt.Sprint(approved))
	return c
}

// CampaignIds sets the optional parameter "campaignIds": Select only
// sites with these campaign IDs.
func (c *SitesListCall) CampaignIds(campaignIds ...int64) *SitesListCall {
	var campaignIds_ []string
	for _, v := range campaignIds {
		campaignIds_ = append(campaignIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("campaignIds", campaignIds_)
	return c
}

// DirectorySiteIds sets the optional parameter "directorySiteIds":
// Select only sites with these directory site IDs.
func (c *SitesListCall) DirectorySiteIds(directorySiteIds ...int64) *SitesListCall {
	var directorySiteIds_ []string
	for _, v := range directorySiteIds {
		directorySiteIds_ = append(directorySiteIds_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("directorySiteIds", directorySiteIds_)
	return c
}

// Ids sets the optional parameter "ids": Select only sites with these
// IDs.
func (c *SitesListCall) Ids(ids ...int64) *SitesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *SitesListCall) MaxResults(maxResults int64) *SitesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *SitesListCall) PageToken(pageToken string) *SitesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name, ID or keyName. Wildcards (*) are
// allowed. For example, "site*2015" will return objects with names like
// "site June 2015", "site April 2015", or simply "site 2015". Most of
// the searches also add wildcards implicitly at the start and the end
// of the search string. For example, a search string of "site" will
// match objects with name "my site", "site 2015", or simply "site".
func (c *SitesListCall) SearchString(searchString string) *SitesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *SitesListCall) SortField(sortField string) *SitesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *SitesListCall) SortOrder(sortOrder string) *SitesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// sites with this subaccount ID.
func (c *SitesListCall) SubaccountId(subaccountId int64) *SitesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// UnmappedSite sets the optional parameter "unmappedSite": Select only
// sites that have not been mapped to a directory site.
func (c *SitesListCall) UnmappedSite(unmappedSite bool) *SitesListCall {
	c.urlParams_.Set("unmappedSite", fmt.Sprint(unmappedSite))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesListCall) Fields(s ...googleapi.Field) *SitesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SitesListCall) IfNoneMatch(entityTag string) *SitesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SitesListCall) Context(ctx context.Context) *SitesListCall {
	c.ctx_ = ctx
	return c
}

func (c *SitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sites")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.list" call.
// Exactly one of *SitesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SitesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SitesListCall) Do(opts ...googleapi.CallOption) (*SitesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SitesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of sites, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sites.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "acceptsInStreamVideoPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsInterstitialPlacements": {
	//       "description": "This search filter is no longer supported and will have no effect on the results returned.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "acceptsPublisherPaidPlacements": {
	//       "description": "Select only sites that accept publisher paid placements.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "adWordsSite": {
	//       "description": "Select only AdWords sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "approved": {
	//       "description": "Select only approved sites.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "campaignIds": {
	//       "description": "Select only sites with these campaign IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "directorySiteIds": {
	//       "description": "Select only sites with these directory site IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only sites with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name, ID or keyName. Wildcards (*) are allowed. For example, \"site*2015\" will return objects with names like \"site June 2015\", \"site April 2015\", or simply \"site 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"site\" will match objects with name \"my site\", \"site 2015\", or simply \"site\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only sites with this subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "unmappedSite": {
	//       "description": "Select only sites that have not been mapped to a directory site.",
	//       "location": "query",
	//       "type": "boolean"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "response": {
	//     "$ref": "SitesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SitesListCall) Pages(ctx context.Context, f func(*SitesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.sites.patch":

type SitesPatchCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing site. This method supports patch
// semantics.
func (r *SitesService) Patch(profileId int64, id int64, site *Site) *SitesPatchCall {
	c := &SitesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.site = site
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesPatchCall) Fields(s ...googleapi.Field) *SitesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SitesPatchCall) Context(ctx context.Context) *SitesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *SitesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.site)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sites")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.patch" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SitesPatchCall) Do(opts ...googleapi.CallOption) (*Site, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Site{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing site. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.sites.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Site ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sites.update":

type SitesUpdateCall struct {
	s          *Service
	profileId  int64
	site       *Site
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing site.
func (r *SitesService) Update(profileId int64, site *Site) *SitesUpdateCall {
	c := &SitesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.site = site
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SitesUpdateCall) Fields(s ...googleapi.Field) *SitesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SitesUpdateCall) Context(ctx context.Context) *SitesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *SitesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.site)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sites")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sites.update" call.
// Exactly one of *Site or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Site.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SitesUpdateCall) Do(opts ...googleapi.CallOption) (*Site, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Site{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing site.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.sites.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sites",
	//   "request": {
	//     "$ref": "Site"
	//   },
	//   "response": {
	//     "$ref": "Site"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.get":

type SizesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one size by ID.
func (r *SizesService) Get(profileId int64, id int64) *SizesGetCall {
	c := &SizesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesGetCall) Fields(s ...googleapi.Field) *SizesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SizesGetCall) IfNoneMatch(entityTag string) *SizesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SizesGetCall) Context(ctx context.Context) *SizesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *SizesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sizes/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.get" call.
// Exactly one of *Size or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Size.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SizesGetCall) Do(opts ...googleapi.CallOption) (*Size, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Size{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one size by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sizes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Size ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes/{id}",
	//   "response": {
	//     "$ref": "Size"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.insert":

type SizesInsertCall struct {
	s          *Service
	profileId  int64
	size       *Size
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new size.
func (r *SizesService) Insert(profileId int64, size *Size) *SizesInsertCall {
	c := &SizesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.size = size
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesInsertCall) Fields(s ...googleapi.Field) *SizesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SizesInsertCall) Context(ctx context.Context) *SizesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *SizesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.size)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sizes")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.insert" call.
// Exactly one of *Size or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Size.ServerResponse.Header or (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *SizesInsertCall) Do(opts ...googleapi.CallOption) (*Size, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Size{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new size.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.sizes.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes",
	//   "request": {
	//     "$ref": "Size"
	//   },
	//   "response": {
	//     "$ref": "Size"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.sizes.list":

type SizesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of sizes, possibly filtered.
func (r *SizesService) List(profileId int64) *SizesListCall {
	c := &SizesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Height sets the optional parameter "height": Select only sizes with
// this height.
func (c *SizesListCall) Height(height int64) *SizesListCall {
	c.urlParams_.Set("height", fmt.Sprint(height))
	return c
}

// IabStandard sets the optional parameter "iabStandard": Select only
// IAB standard sizes.
func (c *SizesListCall) IabStandard(iabStandard bool) *SizesListCall {
	c.urlParams_.Set("iabStandard", fmt.Sprint(iabStandard))
	return c
}

// Ids sets the optional parameter "ids": Select only sizes with these
// IDs.
func (c *SizesListCall) Ids(ids ...int64) *SizesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Width sets the optional parameter "width": Select only sizes with
// this width.
func (c *SizesListCall) Width(width int64) *SizesListCall {
	c.urlParams_.Set("width", fmt.Sprint(width))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SizesListCall) Fields(s ...googleapi.Field) *SizesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SizesListCall) IfNoneMatch(entityTag string) *SizesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SizesListCall) Context(ctx context.Context) *SizesListCall {
	c.ctx_ = ctx
	return c
}

func (c *SizesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/sizes")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.sizes.list" call.
// Exactly one of *SizesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SizesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SizesListCall) Do(opts ...googleapi.CallOption) (*SizesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SizesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of sizes, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.sizes.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "height": {
	//       "description": "Select only sizes with this height.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "iabStandard": {
	//       "description": "Select only IAB standard sizes.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only sizes with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "width": {
	//       "description": "Select only sizes with this width.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/sizes",
	//   "response": {
	//     "$ref": "SizesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.get":

type SubaccountsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one subaccount by ID.
func (r *SubaccountsService) Get(profileId int64, id int64) *SubaccountsGetCall {
	c := &SubaccountsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsGetCall) Fields(s ...googleapi.Field) *SubaccountsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubaccountsGetCall) IfNoneMatch(entityTag string) *SubaccountsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubaccountsGetCall) Context(ctx context.Context) *SubaccountsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *SubaccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/subaccounts/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.get" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsGetCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one subaccount by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.subaccounts.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Subaccount ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts/{id}",
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.insert":

type SubaccountsInsertCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new subaccount.
func (r *SubaccountsService) Insert(profileId int64, subaccount *Subaccount) *SubaccountsInsertCall {
	c := &SubaccountsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.subaccount = subaccount
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsInsertCall) Fields(s ...googleapi.Field) *SubaccountsInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubaccountsInsertCall) Context(ctx context.Context) *SubaccountsInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *SubaccountsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subaccount)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/subaccounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.insert" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsInsertCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new subaccount.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.subaccounts.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.list":

type SubaccountsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Gets a list of subaccounts, possibly filtered.
func (r *SubaccountsService) List(profileId int64) *SubaccountsListCall {
	c := &SubaccountsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only subaccounts with
// these IDs.
func (c *SubaccountsListCall) Ids(ids ...int64) *SubaccountsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *SubaccountsListCall) MaxResults(maxResults int64) *SubaccountsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *SubaccountsListCall) PageToken(pageToken string) *SubaccountsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "subaccount*2015" will return objects with names like
// "subaccount June 2015", "subaccount April 2015", or simply
// "subaccount 2015". Most of the searches also add wildcards implicitly
// at the start and the end of the search string. For example, a search
// string of "subaccount" will match objects with name "my subaccount",
// "subaccount 2015", or simply "subaccount".
func (c *SubaccountsListCall) SearchString(searchString string) *SubaccountsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *SubaccountsListCall) SortField(sortField string) *SubaccountsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *SubaccountsListCall) SortOrder(sortOrder string) *SubaccountsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsListCall) Fields(s ...googleapi.Field) *SubaccountsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *SubaccountsListCall) IfNoneMatch(entityTag string) *SubaccountsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubaccountsListCall) Context(ctx context.Context) *SubaccountsListCall {
	c.ctx_ = ctx
	return c
}

func (c *SubaccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/subaccounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.list" call.
// Exactly one of *SubaccountsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *SubaccountsListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *SubaccountsListCall) Do(opts ...googleapi.CallOption) (*SubaccountsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &SubaccountsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a list of subaccounts, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.subaccounts.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only subaccounts with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"subaccount*2015\" will return objects with names like \"subaccount June 2015\", \"subaccount April 2015\", or simply \"subaccount 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"subaccount\" will match objects with name \"my subaccount\", \"subaccount 2015\", or simply \"subaccount\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "response": {
	//     "$ref": "SubaccountsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *SubaccountsListCall) Pages(ctx context.Context, f func(*SubaccountsListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.subaccounts.patch":

type SubaccountsPatchCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing subaccount. This method supports patch
// semantics.
func (r *SubaccountsService) Patch(profileId int64, id int64, subaccount *Subaccount) *SubaccountsPatchCall {
	c := &SubaccountsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.subaccount = subaccount
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsPatchCall) Fields(s ...googleapi.Field) *SubaccountsPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubaccountsPatchCall) Context(ctx context.Context) *SubaccountsPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *SubaccountsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subaccount)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/subaccounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.patch" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsPatchCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing subaccount. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.subaccounts.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Subaccount ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.subaccounts.update":

type SubaccountsUpdateCall struct {
	s          *Service
	profileId  int64
	subaccount *Subaccount
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing subaccount.
func (r *SubaccountsService) Update(profileId int64, subaccount *Subaccount) *SubaccountsUpdateCall {
	c := &SubaccountsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.subaccount = subaccount
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *SubaccountsUpdateCall) Fields(s ...googleapi.Field) *SubaccountsUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *SubaccountsUpdateCall) Context(ctx context.Context) *SubaccountsUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *SubaccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.subaccount)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/subaccounts")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.subaccounts.update" call.
// Exactly one of *Subaccount or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *Subaccount.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *SubaccountsUpdateCall) Do(opts ...googleapi.CallOption) (*Subaccount, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &Subaccount{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing subaccount.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.subaccounts.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/subaccounts",
	//   "request": {
	//     "$ref": "Subaccount"
	//   },
	//   "response": {
	//     "$ref": "Subaccount"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userProfiles.get":

type UserProfilesGetCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one user profile by ID.
func (r *UserProfilesService) Get(profileId int64) *UserProfilesGetCall {
	c := &UserProfilesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserProfilesGetCall) Fields(s ...googleapi.Field) *UserProfilesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserProfilesGetCall) IfNoneMatch(entityTag string) *UserProfilesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserProfilesGetCall) Context(ctx context.Context) *UserProfilesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *UserProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userProfiles.get" call.
// Exactly one of *UserProfile or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UserProfile.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserProfilesGetCall) Do(opts ...googleapi.CallOption) (*UserProfile, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserProfile{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one user profile by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userProfiles.get",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "The user profile ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}",
	//   "response": {
	//     "$ref": "UserProfile"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting",
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userProfiles.list":

type UserProfilesListCall struct {
	s            *Service
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves list of user profiles for a user.
func (r *UserProfilesService) List() *UserProfilesListCall {
	c := &UserProfilesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserProfilesListCall) Fields(s ...googleapi.Field) *UserProfilesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserProfilesListCall) IfNoneMatch(entityTag string) *UserProfilesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserProfilesListCall) Context(ctx context.Context) *UserProfilesListCall {
	c.ctx_ = ctx
	return c
}

func (c *UserProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userProfiles.list" call.
// Exactly one of *UserProfileList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *UserProfileList.ServerResponse.Header or (if a response was returned
// at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserProfilesListCall) Do(opts ...googleapi.CallOption) (*UserProfileList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserProfileList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of user profiles for a user.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userProfiles.list",
	//   "path": "userprofiles",
	//   "response": {
	//     "$ref": "UserProfileList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfareporting",
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissionGroups.get":

type UserRolePermissionGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one user role permission group by ID.
func (r *UserRolePermissionGroupsService) Get(profileId int64, id int64) *UserRolePermissionGroupsGetCall {
	c := &UserRolePermissionGroupsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionGroupsGetCall) Fields(s ...googleapi.Field) *UserRolePermissionGroupsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolePermissionGroupsGetCall) IfNoneMatch(entityTag string) *UserRolePermissionGroupsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolePermissionGroupsGetCall) Context(ctx context.Context) *UserRolePermissionGroupsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolePermissionGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRolePermissionGroups/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissionGroups.get" call.
// Exactly one of *UserRolePermissionGroup or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolePermissionGroup.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionGroupsGetCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionGroup, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionGroup{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one user role permission group by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissionGroups.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role permission group ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissionGroups/{id}",
	//   "response": {
	//     "$ref": "UserRolePermissionGroup"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissionGroups.list":

type UserRolePermissionGroupsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Gets a list of all supported user role permission groups.
func (r *UserRolePermissionGroupsService) List(profileId int64) *UserRolePermissionGroupsListCall {
	c := &UserRolePermissionGroupsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionGroupsListCall) Fields(s ...googleapi.Field) *UserRolePermissionGroupsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolePermissionGroupsListCall) IfNoneMatch(entityTag string) *UserRolePermissionGroupsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolePermissionGroupsListCall) Context(ctx context.Context) *UserRolePermissionGroupsListCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolePermissionGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRolePermissionGroups")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissionGroups.list" call.
// Exactly one of *UserRolePermissionGroupsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *UserRolePermissionGroupsListResponse.ServerResponse.Header or
// (if a response was returned at all) in
// error.(*googleapi.Error).Header. Use googleapi.IsNotModified to check
// whether the returned error was because http.StatusNotModified was
// returned.
func (c *UserRolePermissionGroupsListCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionGroupsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionGroupsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a list of all supported user role permission groups.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissionGroups.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissionGroups",
	//   "response": {
	//     "$ref": "UserRolePermissionGroupsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissions.get":

type UserRolePermissionsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one user role permission by ID.
func (r *UserRolePermissionsService) Get(profileId int64, id int64) *UserRolePermissionsGetCall {
	c := &UserRolePermissionsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionsGetCall) Fields(s ...googleapi.Field) *UserRolePermissionsGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolePermissionsGetCall) IfNoneMatch(entityTag string) *UserRolePermissionsGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolePermissionsGetCall) Context(ctx context.Context) *UserRolePermissionsGetCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolePermissionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRolePermissions/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissions.get" call.
// Exactly one of *UserRolePermission or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolePermission.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionsGetCall) Do(opts ...googleapi.CallOption) (*UserRolePermission, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermission{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one user role permission by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role permission ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissions/{id}",
	//   "response": {
	//     "$ref": "UserRolePermission"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRolePermissions.list":

type UserRolePermissionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Gets a list of user role permissions, possibly filtered.
func (r *UserRolePermissionsService) List(profileId int64) *UserRolePermissionsListCall {
	c := &UserRolePermissionsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// Ids sets the optional parameter "ids": Select only user role
// permissions with these IDs.
func (c *UserRolePermissionsListCall) Ids(ids ...int64) *UserRolePermissionsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolePermissionsListCall) Fields(s ...googleapi.Field) *UserRolePermissionsListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolePermissionsListCall) IfNoneMatch(entityTag string) *UserRolePermissionsListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolePermissionsListCall) Context(ctx context.Context) *UserRolePermissionsListCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolePermissionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRolePermissions")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRolePermissions.list" call.
// Exactly one of *UserRolePermissionsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *UserRolePermissionsListResponse.ServerResponse.Header or (if
// a response was returned at all) in error.(*googleapi.Error).Header.
// Use googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolePermissionsListCall) Do(opts ...googleapi.CallOption) (*UserRolePermissionsListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolePermissionsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a list of user role permissions, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRolePermissions.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only user role permissions with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRolePermissions",
	//   "response": {
	//     "$ref": "UserRolePermissionsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.delete":

type UserRolesDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Delete: Deletes an existing user role.
func (r *UserRolesService) Delete(profileId int64, id int64) *UserRolesDeleteCall {
	c := &UserRolesDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesDeleteCall) Fields(s ...googleapi.Field) *UserRolesDeleteCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesDeleteCall) Context(ctx context.Context) *UserRolesDeleteCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("DELETE", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.delete" call.
func (c *UserRolesDeleteCall) Do(opts ...googleapi.CallOption) error {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if err != nil {
		return err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return err
	}
	return nil
	// {
	//   "description": "Deletes an existing user role.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.userRoles.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles/{id}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.get":

type UserRolesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// Get: Gets one user role by ID.
func (r *UserRolesService) Get(profileId int64, id int64) *UserRolesGetCall {
	c := &UserRolesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.id = id
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesGetCall) Fields(s ...googleapi.Field) *UserRolesGetCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolesGetCall) IfNoneMatch(entityTag string) *UserRolesGetCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesGetCall) Context(ctx context.Context) *UserRolesGetCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles/{id}")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.get" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesGetCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one user role by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRoles.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles/{id}",
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.insert":

type UserRolesInsertCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Insert: Inserts a new user role.
func (r *UserRolesService) Insert(profileId int64, userrole *UserRole) *UserRolesInsertCall {
	c := &UserRolesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.userrole = userrole
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesInsertCall) Fields(s ...googleapi.Field) *UserRolesInsertCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesInsertCall) Context(ctx context.Context) *UserRolesInsertCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.userrole)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.insert" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesInsertCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new user role.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.userRoles.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.list":

type UserRolesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
}

// List: Retrieves a list of user roles, possibly filtered.
func (r *UserRolesService) List(profileId int64) *UserRolesListCall {
	c := &UserRolesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AccountUserRoleOnly sets the optional parameter
// "accountUserRoleOnly": Select only account level user roles not
// associated with any specific subaccount.
func (c *UserRolesListCall) AccountUserRoleOnly(accountUserRoleOnly bool) *UserRolesListCall {
	c.urlParams_.Set("accountUserRoleOnly", fmt.Sprint(accountUserRoleOnly))
	return c
}

// Ids sets the optional parameter "ids": Select only user roles with
// the specified IDs.
func (c *UserRolesListCall) Ids(ids ...int64) *UserRolesListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *UserRolesListCall) MaxResults(maxResults int64) *UserRolesListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *UserRolesListCall) PageToken(pageToken string) *UserRolesListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for objects by name or ID. Wildcards (*) are allowed. For
// example, "userrole*2015" will return objects with names like
// "userrole June 2015", "userrole April 2015", or simply "userrole
// 2015". Most of the searches also add wildcards implicitly at the
// start and the end of the search string. For example, a search string
// of "userrole" will match objects with name "my userrole", "userrole
// 2015", or simply "userrole".
func (c *UserRolesListCall) SearchString(searchString string) *UserRolesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID"
//   "NAME"
func (c *UserRolesListCall) SortField(sortField string) *UserRolesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results, default is ASCENDING.
//
// Possible values:
//   "ASCENDING"
//   "DESCENDING"
func (c *UserRolesListCall) SortOrder(sortOrder string) *UserRolesListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// SubaccountId sets the optional parameter "subaccountId": Select only
// user roles that belong to this subaccount.
func (c *UserRolesListCall) SubaccountId(subaccountId int64) *UserRolesListCall {
	c.urlParams_.Set("subaccountId", fmt.Sprint(subaccountId))
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesListCall) Fields(s ...googleapi.Field) *UserRolesListCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// IfNoneMatch sets the optional parameter which makes the operation
// fail if the object's ETag matches the given value. This is useful for
// getting updates only after the object has changed since the last
// request. Use googleapi.IsNotModified to check whether the response
// error from Do is the result of In-None-Match.
func (c *UserRolesListCall) IfNoneMatch(entityTag string) *UserRolesListCall {
	c.ifNoneMatch_ = entityTag
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesListCall) Context(ctx context.Context) *UserRolesListCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	if c.ifNoneMatch_ != "" {
		reqHeaders.Set("If-None-Match", c.ifNoneMatch_)
	}
	var body io.Reader = nil
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("GET", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.list" call.
// Exactly one of *UserRolesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *UserRolesListResponse.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *UserRolesListCall) Do(opts ...googleapi.CallOption) (*UserRolesListResponse, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRolesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of user roles, possibly filtered.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.userRoles.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "accountUserRoleOnly": {
	//       "description": "Select only account level user roles not associated with any specific subaccount.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only user roles with the specified IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "description": "Value of the nextPageToken from the previous result page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"userrole*2015\" will return objects with names like \"userrole June 2015\", \"userrole April 2015\", or simply \"userrole 2015\". Most of the searches also add wildcards implicitly at the start and the end of the search string. For example, a search string of \"userrole\" will match objects with name \"my userrole\", \"userrole 2015\", or simply \"userrole\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "description": "Order of sorted results, default is ASCENDING.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "subaccountId": {
	//       "description": "Select only user roles that belong to this subaccount.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "response": {
	//     "$ref": "UserRolesListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// Pages invokes f for each page of results.
// A non-nil error returned from f will halt the iteration.
// The provided context supersedes any context provided to the Context method.
func (c *UserRolesListCall) Pages(ctx context.Context, f func(*UserRolesListResponse) error) error {
	c.ctx_ = ctx
	defer c.PageToken(c.urlParams_.Get("pageToken")) // reset paging to original point
	for {
		x, err := c.Do()
		if err != nil {
			return err
		}
		if err := f(x); err != nil {
			return err
		}
		if x.NextPageToken == "" {
			return nil
		}
		c.PageToken(x.NextPageToken)
	}
}

// method id "dfareporting.userRoles.patch":

type UserRolesPatchCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Patch: Updates an existing user role. This method supports patch
// semantics.
func (r *UserRolesService) Patch(profileId int64, id int64, userrole *UserRole) *UserRolesPatchCall {
	c := &UserRolesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.userrole = userrole
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesPatchCall) Fields(s ...googleapi.Field) *UserRolesPatchCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesPatchCall) Context(ctx context.Context) *UserRolesPatchCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.userrole)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PATCH", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.patch" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesPatchCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing user role. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.userRoles.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "User role ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.userRoles.update":

type UserRolesUpdateCall struct {
	s          *Service
	profileId  int64
	userrole   *UserRole
	urlParams_ gensupport.URLParams
	ctx_       context.Context
}

// Update: Updates an existing user role.
func (r *UserRolesService) Update(profileId int64, userrole *UserRole) *UserRolesUpdateCall {
	c := &UserRolesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.userrole = userrole
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *UserRolesUpdateCall) Fields(s ...googleapi.Field) *UserRolesUpdateCall {
	c.urlParams_.Set("fields", googleapi.CombineFields(s))
	return c
}

// Context sets the context to be used in this call's Do method. Any
// pending HTTP request will be aborted if the provided context is
// canceled.
func (c *UserRolesUpdateCall) Context(ctx context.Context) *UserRolesUpdateCall {
	c.ctx_ = ctx
	return c
}

func (c *UserRolesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.userrole)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	urls := googleapi.ResolveRelative(c.s.BasePath, "userprofiles/{profileId}/userRoles")
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("PUT", urls, body)
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"profileId": strconv.FormatInt(c.profileId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.userRoles.update" call.
// Exactly one of *UserRole or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *UserRole.ServerResponse.Header or (if a response was returned at
// all) in error.(*googleapi.Error).Header. Use googleapi.IsNotModified
// to check whether the returned error was because
// http.StatusNotModified was returned.
func (c *UserRolesUpdateCall) Do(opts ...googleapi.CallOption) (*UserRole, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &UserRole{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := json.NewDecoder(res.Body).Decode(target); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing user role.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.userRoles.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/userRoles",
	//   "request": {
	//     "$ref": "UserRole"
	//   },
	//   "response": {
	//     "$ref": "UserRole"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}
