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

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.7"
const apiName = "dfareporting"
const apiVersion = "v2.7"
const basePath = "https://www.googleapis.com/dfareporting/v2.7/"

// OAuth2 scopes used by this API.
const (
	// Manage DoubleClick Digital Marketing conversions
	DdmconversionsScope = "https://www.googleapis.com/auth/ddmconversions"

	// 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.Conversions = NewConversionsService(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.DynamicTargetingKeys = NewDynamicTargetingKeysService(s)
	s.EventTags = NewEventTagsService(s)
	s.Files = NewFilesService(s)
	s.FloodlightActivities = NewFloodlightActivitiesService(s)
	s.FloodlightActivityGroups = NewFloodlightActivityGroupsService(s)
	s.FloodlightConfigurations = NewFloodlightConfigurationsService(s)
	s.InventoryItems = NewInventoryItemsService(s)
	s.LandingPages = NewLandingPagesService(s)
	s.Languages = NewLanguagesService(s)
	s.Metros = NewMetrosService(s)
	s.MobileCarriers = NewMobileCarriersService(s)
	s.OperatingSystemVersions = NewOperatingSystemVersionsService(s)
	s.OperatingSystems = NewOperatingSystemsService(s)
	s.OrderDocuments = NewOrderDocumentsService(s)
	s.Orders = NewOrdersService(s)
	s.PlacementGroups = NewPlacementGroupsService(s)
	s.PlacementStrategies = NewPlacementStrategiesService(s)
	s.Placements = NewPlacementsService(s)
	s.PlatformTypes = NewPlatformTypesService(s)
	s.PostalCodes = NewPostalCodesService(s)
	s.Projects = NewProjectsService(s)
	s.Regions = NewRegionsService(s)
	s.RemarketingListShares = NewRemarketingListSharesService(s)
	s.RemarketingLists = NewRemarketingListsService(s)
	s.Reports = NewReportsService(s)
	s.Sites = NewSitesService(s)
	s.Sizes = NewSizesService(s)
	s.Subaccounts = NewSubaccountsService(s)
	s.TargetableRemarketingLists = NewTargetableRemarketingListsService(s)
	s.TargetingTemplates = NewTargetingTemplatesService(s)
	s.UserProfiles = NewUserProfilesService(s)
	s.UserRolePermissionGroups = NewUserRolePermissionGroupsService(s)
	s.UserRolePermissions = NewUserRolePermissionsService(s)
	s.UserRoles = NewUserRolesService(s)
	s.VideoFormats = NewVideoFormatsService(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

	Conversions *ConversionsService

	Countries *CountriesService

	CreativeAssets *CreativeAssetsService

	CreativeFieldValues *CreativeFieldValuesService

	CreativeFields *CreativeFieldsService

	CreativeGroups *CreativeGroupsService

	Creatives *CreativesService

	DimensionValues *DimensionValuesService

	DirectorySiteContacts *DirectorySiteContactsService

	DirectorySites *DirectorySitesService

	DynamicTargetingKeys *DynamicTargetingKeysService

	EventTags *EventTagsService

	Files *FilesService

	FloodlightActivities *FloodlightActivitiesService

	FloodlightActivityGroups *FloodlightActivityGroupsService

	FloodlightConfigurations *FloodlightConfigurationsService

	InventoryItems *InventoryItemsService

	LandingPages *LandingPagesService

	Languages *LanguagesService

	Metros *MetrosService

	MobileCarriers *MobileCarriersService

	OperatingSystemVersions *OperatingSystemVersionsService

	OperatingSystems *OperatingSystemsService

	OrderDocuments *OrderDocumentsService

	Orders *OrdersService

	PlacementGroups *PlacementGroupsService

	PlacementStrategies *PlacementStrategiesService

	Placements *PlacementsService

	PlatformTypes *PlatformTypesService

	PostalCodes *PostalCodesService

	Projects *ProjectsService

	Regions *RegionsService

	RemarketingListShares *RemarketingListSharesService

	RemarketingLists *RemarketingListsService

	Reports *ReportsService

	Sites *SitesService

	Sizes *SizesService

	Subaccounts *SubaccountsService

	TargetableRemarketingLists *TargetableRemarketingListsService

	TargetingTemplates *TargetingTemplatesService

	UserProfiles *UserProfilesService

	UserRolePermissionGroups *UserRolePermissionGroupsService

	UserRolePermissions *UserRolePermissionsService

	UserRoles *UserRolesService

	VideoFormats *VideoFormatsService
}

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 NewConversionsService(s *Service) *ConversionsService {
	rs := &ConversionsService{s: s}
	return rs
}

type ConversionsService 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 NewDynamicTargetingKeysService(s *Service) *DynamicTargetingKeysService {
	rs := &DynamicTargetingKeysService{s: s}
	return rs
}

type DynamicTargetingKeysService 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 NewInventoryItemsService(s *Service) *InventoryItemsService {
	rs := &InventoryItemsService{s: s}
	return rs
}

type InventoryItemsService struct {
	s *Service
}

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

type LandingPagesService struct {
	s *Service
}

func NewLanguagesService(s *Service) *LanguagesService {
	rs := &LanguagesService{s: s}
	return rs
}

type LanguagesService 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 NewOrderDocumentsService(s *Service) *OrderDocumentsService {
	rs := &OrderDocumentsService{s: s}
	return rs
}

type OrderDocumentsService struct {
	s *Service
}

func NewOrdersService(s *Service) *OrdersService {
	rs := &OrdersService{s: s}
	return rs
}

type OrdersService 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 NewProjectsService(s *Service) *ProjectsService {
	rs := &ProjectsService{s: s}
	return rs
}

type ProjectsService struct {
	s *Service
}

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

type RegionsService struct {
	s *Service
}

func NewRemarketingListSharesService(s *Service) *RemarketingListSharesService {
	rs := &RemarketingListSharesService{s: s}
	return rs
}

type RemarketingListSharesService struct {
	s *Service
}

func NewRemarketingListsService(s *Service) *RemarketingListsService {
	rs := &RemarketingListsService{s: s}
	return rs
}

type RemarketingListsService 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 NewTargetableRemarketingListsService(s *Service) *TargetableRemarketingListsService {
	rs := &TargetableRemarketingListsService{s: s}
	return rs
}

type TargetableRemarketingListsService struct {
	s *Service
}

func NewTargetingTemplatesService(s *Service) *TargetingTemplatesService {
	rs := &TargetingTemplatesService{s: s}
	return rs
}

type TargetingTemplatesService 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
}

func NewVideoFormatsService(s *Service) *VideoFormatsService {
	rs := &VideoFormatsService{s: s}
	return rs
}

type VideoFormatsService 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_1M"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_500K"
	//   "ACTIVE_ADS_TIER_750K"
	//   "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"`

	// 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
	// - "49" for MXN
	// - "50" for NGN
	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, in
	// kilobytes. Value must be greater than or equal to 1.
	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"`

	// ShareReportsWithTwitter: Share Path to Conversion reports with
	// Twitter.
	ShareReportsWithTwitter bool `json:"shareReportsWithTwitter,omitempty"`

	// TeaserSizeLimit: File size limit in kilobytes of Rich Media teaser
	// creatives. Acceptable values are 1 to 10240, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountPermissionIds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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_1M"
	//   "ACTIVE_ADS_TIER_200K"
	//   "ACTIVE_ADS_TIER_300K"
	//   "ACTIVE_ADS_TIER_40K"
	//   "ACTIVE_ADS_TIER_500K"
	//   "ACTIVE_ADS_TIER_750K"
	//   "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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountProfiles") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountPermissionGroups")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountPermissions") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountUserProfiles") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Accounts") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Filters") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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. When true, archived must be false.
	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. When true, active must be
	// false.
	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. DISPLAY and DISPLAY_INTERSTITIAL refer to
	// either rendering on desktop or on mobile devices or in mobile apps
	// for regular or interstitial ads, respectively. APP and
	// APP_INTERSTITIAL are only used for existing default ads. New mobile
	// placements must be assigned DISPLAY or DISPLAY_INTERSTITIAL and
	// default ads created for those placements will be limited to those
	// compatibility types. IN_STREAM_VIDEO refers to rendering in-stream
	// video ads developed with the VAST standard.
	//
	// Possible values:
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	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.
	// This field must be left blank if the ad is using a targeting
	// template. 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. This
	// field must be left blank if the ad is using a targeting template.
	// 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. This field must be left blank if the ad is using a targeting
	// template. 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"`

	// LanguageTargeting: Language targeting information for this ad. This
	// field must be left blank if the ad is using a targeting template.
	// Applicable when type is AD_SERVING_STANDARD_AD.
	LanguageTargeting *LanguageTargeting `json:"languageTargeting,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: Remarketing list targeting expression for
	// this ad. This field must be left blank if the ad is using a targeting
	// template. Applicable when type is AD_SERVING_STANDARD_AD.
	RemarketingListExpression *ListTargetingExpression `json:"remarketingListExpression,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"`

	// TargetingTemplateId: Targeting template ID, used to apply
	// preconfigured targeting information to this ad. This cannot be set
	// while any of dayPartTargeting, geoTargeting,
	// keyValueTargetingExpression, languageTargeting,
	// remarketingListExpression, or technologyTargeting are set. Applicable
	// when type is AD_SERVING_STANDARD_AD.
	TargetingTemplateId int64 `json:"targetingTemplateId,omitempty,string"`

	// TechnologyTargeting: Technology platform targeting information for
	// this ad. This field must be left blank if the ad is using a targeting
	// template. 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// AdSlot: Ad Slot
type AdSlot struct {
	// Comment: Comment for this ad slot.
	Comment string `json:"comment,omitempty"`

	// Compatibility: Ad slot compatibility. DISPLAY and
	// DISPLAY_INTERSTITIAL refer to rendering either on desktop, mobile
	// devices or in mobile apps 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"
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	Compatibility string `json:"compatibility,omitempty"`

	// Height: Height of this ad slot.
	Height int64 `json:"height,omitempty,string"`

	// LinkedPlacementId: ID of the placement from an external platform that
	// is linked to this ad slot.
	LinkedPlacementId int64 `json:"linkedPlacementId,omitempty,string"`

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

	// PaymentSourceType: Payment source type of this ad slot.
	//
	// Possible values:
	//   "PLANNING_PAYMENT_SOURCE_TYPE_AGENCY_PAID"
	//   "PLANNING_PAYMENT_SOURCE_TYPE_PUBLISHER_PAID"
	PaymentSourceType string `json:"paymentSourceType,omitempty"`

	// Primary: Primary ad slot of a roadblock inventory item.
	Primary bool `json:"primary,omitempty"`

	// Width: Width of this ad slot.
	Width int64 `json:"width,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "Comment") 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:"-"`

	// NullFields is a list of field names (e.g. "Comment") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Ads") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// OriginalFloodlightConfigurationId: Original floodlight configuration
	// before any sharing occurred. Set the floodlightConfigurationId of
	// this advertiser to originalFloodlightConfigurationId to unshare the
	// advertiser's current floodlight configuration. You cannot unshare an
	// advertiser's floodlight configuration if the shared configuration has
	// activities associated with any campaign or placement.
	OriginalFloodlightConfigurationId int64 `json:"originalFloodlightConfigurationId,omitempty,string"`

	// 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"`

	// Suspended: Suspension status of this advertiser.
	Suspended bool `json:"suspended,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AdvertiserGroups") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Advertisers") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// AudienceSegment: Audience Segment.
type AudienceSegment struct {
	// Allocation: Weight allocated to this segment. The weight assigned
	// will be understood in proportion to the weights assigned to other
	// segments in the same segment group. Acceptable values are 1 to 1000,
	// inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "Allocation") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AudienceSegments") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "BrowserVersionId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Browsers") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g.
	// "CampaignCreativeAssociations") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Campaigns") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ChangeLogs") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Cities") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CountryCode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ClickTag: Creative Click Tag.
type ClickTag struct {
	// EventName: Advertiser event name associated with the click tag. This
	// field is used by DISPLAY_IMAGE_GALLERY and HTML5_BANNER creatives.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	EventName string `json:"eventName,omitempty"`

	// Name: Parameter name for the specified click tag. For
	// DISPLAY_IMAGE_GALLERY 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:"-"`

	// NullFields is a list of field names (e.g. "EventName") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ClickThroughUrl: Click-through URL
type ClickThroughUrl struct {
	// ComputedClickThroughUrl: Read-only convenience field representing the
	// actual URL that will be used for this click-through. The URL is
	// computed as follows:
	// - If defaultLandingPage is enabled then the campaign's default
	// landing page URL is assigned to this field.
	// - If defaultLandingPage is not enabled and a landingPageId is
	// specified then that landing page's URL is assigned to this field.
	// - If neither of the above cases apply, then the customClickThroughUrl
	// is assigned to this field.
	ComputedClickThroughUrl string `json:"computedClickThroughUrl,omitempty"`

	// 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.
	// "ComputedClickThroughUrl") 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:"-"`

	// NullFields is a list of field names (e.g. "ComputedClickThroughUrl")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ClickThroughUrlSuffix") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ClickThroughUrl") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// CompanionSetting: Companion Settings
type CompanionSetting struct {
	// CompanionsDisabled: Whether companions are disabled for this
	// placement.
	CompanionsDisabled bool `json:"companionsDisabled,omitempty"`

	// EnabledSizes: Whitelist of companion sizes to be served to this
	// placement. Set this list to null or empty to serve all companion
	// sizes.
	EnabledSizes []*Size `json:"enabledSizes,omitempty"`

	// ImageOnly: Whether to serve only static images as companions.
	ImageOnly bool `json:"imageOnly,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "CompanionsDisabled")
	// 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:"-"`

	// NullFields is a list of field names (e.g. "CompanionsDisabled") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g.
	// "CrossDimensionReachReportCompatibleFields") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ConnectionTypes") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ContentCategories") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Conversion: A Conversion represents when a user successfully performs
// a desired action after seeing an ad.
type Conversion struct {
	// ChildDirectedTreatment: Whether the conversion was directed toward
	// children.
	ChildDirectedTreatment bool `json:"childDirectedTreatment,omitempty"`

	// CustomVariables: Custom floodlight variables.
	CustomVariables []*CustomFloodlightVariable `json:"customVariables,omitempty"`

	// EncryptedUserId: The alphanumeric encrypted user ID. When set,
	// encryptionInfo should also be specified. This field is mutually
	// exclusive with encryptedUserIdCandidates[] and mobileDeviceId. This
	// or encryptedUserIdCandidates[] or mobileDeviceId is a required field.
	EncryptedUserId string `json:"encryptedUserId,omitempty"`

	// EncryptedUserIdCandidates: A list of the alphanumeric encrypted user
	// IDs. Any user ID with exposure prior to the conversion timestamp will
	// be used in the inserted conversion. If no such user ID is found then
	// the conversion will be rejected with NO_COOKIE_MATCH_FOUND error.
	// When set, encryptionInfo should also be specified. This field should
	// only be used when calling conversions.batchinsert. This field is
	// mutually exclusive with encryptedUserId and mobileDeviceId. This or
	// encryptedUserId or mobileDeviceId is a required field.
	EncryptedUserIdCandidates []string `json:"encryptedUserIdCandidates,omitempty"`

	// FloodlightActivityId: Floodlight Activity ID of this conversion. This
	// is a required field.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightConfigurationId: Floodlight Configuration ID of this
	// conversion. This is a required field.
	FloodlightConfigurationId int64 `json:"floodlightConfigurationId,omitempty,string"`

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

	// LimitAdTracking: Whether Limit Ad Tracking is enabled. When set to
	// true, the conversion will be used for reporting but not targeting.
	// This will prevent remarketing.
	LimitAdTracking bool `json:"limitAdTracking,omitempty"`

	// MobileDeviceId: The mobile device ID. This field is mutually
	// exclusive with encryptedUserId and encryptedUserIdCandidates[]. This
	// or encryptedUserId or encryptedUserIdCandidates[] is a required
	// field.
	MobileDeviceId string `json:"mobileDeviceId,omitempty"`

	// Ordinal: The ordinal of the conversion. Use this field to control how
	// conversions of the same user and day are de-duplicated. This is a
	// required field.
	Ordinal string `json:"ordinal,omitempty"`

	// Quantity: The quantity of the conversion.
	Quantity int64 `json:"quantity,omitempty,string"`

	// TimestampMicros: The timestamp of conversion, in Unix epoch micros.
	// This is a required field.
	TimestampMicros int64 `json:"timestampMicros,omitempty,string"`

	// Value: The value of the conversion.
	Value float64 `json:"value,omitempty"`

	// ForceSendFields is a list of field names (e.g.
	// "ChildDirectedTreatment") 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:"-"`

	// NullFields is a list of field names (e.g. "ChildDirectedTreatment")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

func (s *Conversion) UnmarshalJSON(data []byte) error {
	type NoMethod Conversion
	var s1 struct {
		Value gensupport.JSONFloat64 `json:"value"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.Value = float64(s1.Value)
	return nil
}

// ConversionError: The error code and description for a conversion that
// failed to insert or update.
type ConversionError struct {
	// Code: The error code.
	//
	// Possible values:
	//   "INTERNAL"
	//   "INVALID_ARGUMENT"
	//   "NOT_FOUND"
	//   "PERMISSION_DENIED"
	Code string `json:"code,omitempty"`

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

	// Message: A description of the error.
	Message string `json:"message,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Code") 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:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ConversionStatus: The original conversion that was inserted or
// updated and whether there were any errors.
type ConversionStatus struct {
	// Conversion: The original conversion that was inserted or updated.
	Conversion *Conversion `json:"conversion,omitempty"`

	// Errors: A list of errors related to this conversion.
	Errors []*ConversionError `json:"errors,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Conversion") 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:"-"`

	// NullFields is a list of field names (e.g. "Conversion") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ConversionsBatchInsertRequest: Insert Conversions Request.
type ConversionsBatchInsertRequest struct {
	// Conversions: The set of conversions to insert.
	Conversions []*Conversion `json:"conversions,omitempty"`

	// EncryptionInfo: Describes how encryptedUserId or
	// encryptedUserIdCandidates[] is encrypted. This is a required field if
	// encryptedUserId or encryptedUserIdCandidates[] is used.
	EncryptionInfo *EncryptionInfo `json:"encryptionInfo,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Conversions") 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:"-"`

	// NullFields is a list of field names (e.g. "Conversions") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ConversionsBatchInsertResponse: Insert Conversions Response.
type ConversionsBatchInsertResponse struct {
	// HasFailures: Indicates that some or all conversions failed to insert.
	HasFailures bool `json:"hasFailures,omitempty"`

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

	// Status: The insert status of each conversion. Statuses are returned
	// in the same order that conversions are inserted.
	Status []*ConversionStatus `json:"status,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "HasFailures") 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:"-"`

	// NullFields is a list of field names (e.g. "HasFailures") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Countries") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CountryCode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// AuthoringSource: Source application where creative was authored.
	// Presently, only DBM authored creatives will have this field set.
	// Applicable to all creative types.
	//
	// Possible values:
	//   "CREATIVE_AUTHORING_SOURCE_DBM"
	//   "CREATIVE_AUTHORING_SOURCE_DCM"
	//   "CREATIVE_AUTHORING_SOURCE_STUDIO"
	AuthoringSource string `json:"authoringSource,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
	// image gallery creatives. Applicable to the following creative types:
	// DISPLAY_IMAGE_GALLERY.
	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: FLASH_INPAGE, and
	// HTML5_BANNER. Applicable to DISPLAY when the primary asset type is
	// not HTML_IMAGE.
	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: HTML5_BANNER. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	//
	// 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: DISPLAY
	// when the primary asset type is not HTML_IMAGE.
	BackupImageReportingLabel string `json:"backupImageReportingLabel,omitempty"`

	// BackupImageTargetWindow: Target window for backup image. Applicable
	// to the following creative types: FLASH_INPAGE and HTML5_BANNER.
	// Applicable to DISPLAY when the primary asset type is not HTML_IMAGE.
	BackupImageTargetWindow *TargetWindow `json:"backupImageTargetWindow,omitempty"`

	// ClickTags: Click tags of the creative. For DISPLAY, 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 DISPLAY_IMAGE_GALLERY 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:
	// DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER. Applicable to
	// DISPLAY when the primary asset type is not HTML_IMAGE.
	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 VPAID and all INSTREAM_VIDEO with dynamicAssetSelection
	// set to false.
	CompanionCreatives googleapi.Int64s `json:"companionCreatives,omitempty"`

	// Compatibility: Compatibilities associated with this creative. This is
	// a read-only field. DISPLAY and DISPLAY_INTERSTITIAL refer to
	// rendering either on desktop or on mobile devices or in mobile apps
	// for regular or interstitial ads, respectively. APP and
	// APP_INTERSTITIAL are for rendering in mobile apps. Only pre-existing
	// creatives may have these compatibilities since new creatives will
	// either be assigned DISPLAY or DISPLAY_INTERSTITIAL instead.
	// 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"
	// - "DISPLAY"
	// - "DISPLAY_INTERSTITIAL"
	//
	// Possible values:
	//   "APP"
	//   "APP_INTERSTITIAL"
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	Compatibility []string `json:"compatibility,omitempty"`

	// ConvertFlashToHtml5: Whether Flash assets associated with the
	// creative need to be automatically converted to HTML5. This flag is
	// enabled by default and users can choose to disable it if they don't
	// want the system to generate and use HTML5 asset for this creative.
	// Applicable to the following creative type: FLASH_INPAGE. Applicable
	// to DISPLAY when the primary asset type is not HTML_IMAGE.
	ConvertFlashToHtml5 bool `json:"convertFlashToHtml5,omitempty"`

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

	// CreativeAssetSelection: Required if dynamicAssetSelection is true.
	CreativeAssetSelection *CreativeAssetSelection `json:"creativeAssetSelection,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"`

	// DynamicAssetSelection: Set this to true to enable the use of rules to
	// target individual assets in this creative. When set to true
	// creativeAssetSelection must be set. This also controls asset-level
	// companions. When this is true, companion creatives should be assigned
	// to creative assets. Learn more. Applicable to INSTREAM_VIDEO
	// creatives.
	DynamicAssetSelection bool `json:"dynamicAssetSelection,omitempty"`

	// ExitCustomEvents: List of exit events configured for the creative.
	// For DISPLAY and DISPLAY_IMAGE_GALLERY creatives, these are read-only
	// and auto-generated from clickTags, For DISPLAY, an event is also
	// created from the backupImageReportingLabel. Applicable to the
	// following creative types: DISPLAY_IMAGE_GALLERY, all RICH_MEDIA, and
	// all VPAID. Applicable to DISPLAY when the primary asset type is not
	// HTML_IMAGE.
	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 true.
	// 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"`

	// ProgressOffset: Amount of time to play the video before counting a
	// view. Applicable to the following creative types: all INSTREAM_VIDEO.
	ProgressOffset *VideoOffset `json:"progressOffset,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: DISPLAY_REDIRECT, INTERNAL_REDIRECT,
	// INTERSTITIAL_INTERNAL_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 all
	// RICH_MEDIA, and all VPAID. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	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, FLASH_INPAGE creatives, and for DISPLAY creatives with a
	// primary asset of type HTML_IMAGE, if left blank, this field will be
	// automatically set using the actual size of the associated image
	// assets. Applicable to the following creative types: DISPLAY,
	// DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER, IMAGE, and all
	// RICH_MEDIA.
	Size *Size `json:"size,omitempty"`

	// SkipOffset: Amount of time to play the video before the skip button
	// appears. Applicable to the following creative types: all
	// INSTREAM_VIDEO.
	SkipOffset *VideoOffset `json:"skipOffset,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"`

	// SslOverride: Whether creative should be treated as SSL compliant even
	// if the system scan shows it's not. Applicable to all creative types.
	SslOverride bool `json:"sslOverride,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 DISPLAY_IMAGE_GALLERY creatives, these are read-only and
	// auto-generated from clickTags. Applicable to the following creative
	// types: DISPLAY_IMAGE_GALLERY, all RICH_MEDIA, and all VPAID.
	// Applicable to DISPLAY when the primary asset is not HTML_IMAGE.
	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.
	//
	// Note: FLASH_INPAGE, HTML5_BANNER, and IMAGE are only used for
	// existing creatives. New creatives should use DISPLAY as a replacement
	// for these types.
	//
	// Possible values:
	//   "BRAND_SAFE_DEFAULT_INSTREAM_VIDEO"
	//   "CUSTOM_DISPLAY"
	//   "CUSTOM_DISPLAY_INTERSTITIAL"
	//   "DISPLAY"
	//   "DISPLAY_IMAGE_GALLERY"
	//   "DISPLAY_REDIRECT"
	//   "FLASH_INPAGE"
	//   "HTML5_BANNER"
	//   "IMAGE"
	//   "INSTREAM_VIDEO"
	//   "INSTREAM_VIDEO_REDIRECT"
	//   "INTERNAL_REDIRECT"
	//   "INTERSTITIAL_INTERNAL_REDIRECT"
	//   "RICH_MEDIA_DISPLAY_BANNER"
	//   "RICH_MEDIA_DISPLAY_EXPANDING"
	//   "RICH_MEDIA_DISPLAY_INTERSTITIAL"
	//   "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL"
	//   "RICH_MEDIA_IM_EXPAND"
	//   "RICH_MEDIA_INPAGE_FLOATING"
	//   "RICH_MEDIA_MOBILE_IN_APP"
	//   "RICH_MEDIA_PEEL_DOWN"
	//   "TRACKING_TEXT"
	//   "VPAID_LINEAR_VIDEO"
	//   "VPAID_NON_LINEAR_VIDEO"
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

func (s *Creative) UnmarshalJSON(data []byte) error {
	type NoMethod Creative
	var s1 struct {
		VideoDuration gensupport.JSONFloat64 `json:"videoDuration"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.VideoDuration = float64(s1.VideoDuration)
	return nil
}

// 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 type:
	// FLASH_INPAGE. Applicable to DISPLAY when the primary asset type is
	// not HTML_IMAGE.
	ActionScript3 bool `json:"actionScript3,omitempty"`

	// Active: Whether the video asset is active. This is a read-only field
	// for VPAID_NON_LINEAR_VIDEO 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_DISPLAY_MULTI_FLOATING_INTERSTITIAL.
	//
	// 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"`

	// CompanionCreativeIds: List of companion creatives assigned to an
	// in-stream video creative asset. Acceptable values include IDs of
	// existing flash and image creatives. Applicable to INSTREAM_VIDEO
	// creative type with dynamicAssetSelection set to true.
	CompanionCreativeIds googleapi.Int64s `json:"companionCreativeIds,omitempty"`

	// CustomStartTimeValue: Custom start time in seconds for making the
	// asset visible. Applicable to the following creative types: all
	// RICH_MEDIA. Value must be greater than or equal to 0.
	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: HTML5_BANNER. Applicable
	// to DISPLAY when the primary asset type is not HTML_IMAGE.
	//
	// 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_BACKDROP"
	//   "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_VIDEO. Value must be greater than or equal to 1.
	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, all
	// RICH_MEDIA, and all VPAID. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	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"`

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

	// 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.
	// 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.
	// Acceptable values are 0 to 9.99, inclusive.
	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 DISPLAY, FLASH_INPAGE, HTML5_BANNER, IMAGE,
	// DISPLAY_IMAGE_GALLERY, all RICH_MEDIA (which may contain multiple
	// primary assets), and all VPAID creatives.
	// BACKUP_IMAGE applies to FLASH_INPAGE, HTML5_BANNER, all RICH_MEDIA,
	// and all VPAID creatives. Applicable to DISPLAY when the primary asset
	// type is not HTML_IMAGE.
	// 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_VIDEO
	// creatives.
	// TRANSCODED_VIDEO refers to videos transcoded by DCM from PARENT_VIDEO
	// assets and is applicable to INSTREAM_VIDEO and VPAID_LINEAR_VIDEO
	// creatives.
	// ALTERNATE_VIDEO refers to the DCM representation of child asset
	// videos from Studio, and is applicable to VPAID_LINEAR_VIDEO
	// creatives. These cannot be added or removed within DCM.
	// For VPAID_LINEAR_VIDEO 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_VIDEO
	// 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: DISPLAY_IMAGE_GALLERY, FLASH_INPAGE, HTML5_BANNER,
	// IMAGE, and all RICH_MEDIA. Applicable to DISPLAY when the primary
	// asset type is not HTML_IMAGE.
	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_DISPLAY_EXPANDING,
	// RICH_MEDIA_IM_EXPAND, RICH_MEDIA_DISPLAY_BANNER, and
	// RICH_MEDIA_INPAGE_FLOATING.
	//
	// Possible values:
	//   "OPAQUE"
	//   "TRANSPARENT"
	//   "WINDOW"
	WindowMode string `json:"windowMode,omitempty"`

	// ZIndex: zIndex value of an asset. 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. Acceptable
	// values are -999999999 to 999999999, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "ActionScript3") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

func (s *CreativeAsset) UnmarshalJSON(data []byte) error {
	type NoMethod CreativeAsset
	var s1 struct {
		PushdownDuration gensupport.JSONFloat64 `json:"pushdownDuration"`
		VideoDuration    gensupport.JSONFloat64 `json:"videoDuration"`
		*NoMethod
	}
	s1.NoMethod = (*NoMethod)(s)
	if err := json.Unmarshal(data, &s1); err != nil {
		return err
	}
	s.PushdownDuration = float64(s1.PushdownDuration)
	s.VideoDuration = float64(s1.VideoDuration)
	return nil
}

// 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. FLASH and
	// IMAGE are no longer supported for new uploads. All 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:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

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

	// IdDimensionValue: Dimension value for the numeric ID of the asset.
	// 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#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:
	// - "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"
	//
	// 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:"-"`

	// NullFields is a list of field names (e.g. "AssetIdentifier") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// CreativeAssetSelection: Encapsulates the list of rules for asset
// selection and a default asset in case none of the rules match.
// Applicable to INSTREAM_VIDEO creatives.
type CreativeAssetSelection struct {
	// DefaultAssetId: A creativeAssets[].id. This should refer to one of
	// the parent assets in this creative, and will be served if none of the
	// rules match. This is a required field.
	DefaultAssetId int64 `json:"defaultAssetId,omitempty,string"`

	// Rules: Rules determine which asset will be served to a viewer. Rules
	// will be evaluated in the order in which they are stored in this list.
	// This list must contain at least one rule. Applicable to
	// INSTREAM_VIDEO creatives.
	Rules []*Rule `json:"rules,omitempty"`

	// ForceSendFields is a list of field names (e.g. "DefaultAssetId") 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:"-"`

	// NullFields is a list of field names (e.g. "DefaultAssetId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:
	// - DISPLAY
	// - 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
	// - 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. Acceptable
	// values are 1 to 65535, inclusive.
	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. Value must be greater
	// than or equal to 1.
	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:"-"`

	// NullFields is a list of field names (e.g. "Active") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// CreativeCustomEvent: Creative Custom Event.
type CreativeCustomEvent struct {
	// AdvertiserCustomEventId: Unique ID of this event used by DDM
	// Reporting and Data Transfer. This is a read-only field.
	AdvertiserCustomEventId int64 `json:"advertiserCustomEventId,omitempty,string"`

	// 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.
	// "AdvertiserCustomEventId") 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:"-"`

	// NullFields is a list of field names (e.g. "AdvertiserCustomEventId")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeFieldId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeFieldValues") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeFields") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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 a subgroup 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 to 2, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeGroupId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeGroups") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CreativeAssignments") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "IFrameFooter") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Creatives") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Breakdown") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// CustomFloodlightVariable: A custom floodlight variable.
type CustomFloodlightVariable struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#customFloodlightVariable".
	Kind string `json:"kind,omitempty"`

	// Type: The type of custom floodlight variable to supply a value for.
	// These map to the "u[1-20]=" in the tags.
	//
	// Possible values:
	//   "U1"
	//   "U10"
	//   "U100"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U2"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U3"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U4"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U5"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U6"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U7"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U8"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U9"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	Type string `json:"type,omitempty"`

	// Value: The value of the custom floodlight variable. The length of
	// string must not exceed 50 characters.
	Value string `json:"value,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "FilteredEventIds") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "EndDate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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, 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. Acceptable values are 0 to 23, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "DaysOfWeek") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g.
	// "DefaultClickThroughEventTagId") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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. Acceptable
	// values are 1 to 10, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "FrequencyCap") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DfpNetworkCode") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionName") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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. This is a read-only
	// field.
	CountryId int64 `json:"countryId,omitempty,string"`

	// CurrencyId: Currency ID of this directory site. This is a read-only
	// field.
	// 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
	// - "49" for MXN
	// - "50" for NGN
	CurrencyId int64 `json:"currencyId,omitempty,string"`

	// Description: Description of this directory site. This is a read-only
	// field.
	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:"-"`

	// NullFields is a list of field names (e.g. "Active") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

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

	// 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"`

	// Phone: Phone number of this directory site contact.
	Phone string `json:"phone,omitempty"`

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

	// Title: Title or designation of this directory site contact.
	Title string `json:"title,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. "Address") 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:"-"`

	// NullFields is a list of field names (e.g. "Address") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ContactId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DirectorySiteContacts") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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. This is a read-only field.
	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:"-"`

	// NullFields is a list of field names (e.g. "ActiveViewOptOut") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DirectorySites") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// DynamicTargetingKey: Contains properties of a dynamic targeting key.
// Dynamic targeting keys are unique, user-friendly labels, created at
// the advertiser level in DCM, that can be assigned to ads, creatives,
// and placements and used for targeting with DoubleClick Studio dynamic
// creatives. Use these labels instead of numeric DCM IDs (such as
// placement IDs) to save time and avoid errors in your dynamic feeds.
type DynamicTargetingKey struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#dynamicTargetingKey".
	Kind string `json:"kind,omitempty"`

	// Name: Name of this dynamic targeting key. This is a required field.
	// Must be less than 256 characters long and cannot contain commas. All
	// characters are converted to lowercase.
	Name string `json:"name,omitempty"`

	// ObjectId: ID of the object of this dynamic targeting key. This is a
	// required field.
	ObjectId int64 `json:"objectId,omitempty,string"`

	// ObjectType: Type of the object of this dynamic targeting key. This is
	// a required field.
	//
	// Possible values:
	//   "OBJECT_AD"
	//   "OBJECT_ADVERTISER"
	//   "OBJECT_CREATIVE"
	//   "OBJECT_PLACEMENT"
	ObjectType string `json:"objectType,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// DynamicTargetingKeysListResponse: Dynamic Targeting Key List Response
type DynamicTargetingKeysListResponse struct {
	// DynamicTargetingKeys: Dynamic targeting key collection.
	DynamicTargetingKeys []*DynamicTargetingKey `json:"dynamicTargetingKeys,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#dynamicTargetingKeysListResponse".
	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.
	// "DynamicTargetingKeys") 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:"-"`

	// NullFields is a list of field names (e.g. "DynamicTargetingKeys") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// EncryptionInfo: A description of how user IDs are encrypted.
type EncryptionInfo struct {
	// EncryptionEntityId: The encryption entity ID. This should match the
	// encryption configuration for ad serving or Data Transfer.
	EncryptionEntityId int64 `json:"encryptionEntityId,omitempty,string"`

	// EncryptionEntityType: The encryption entity type. This should match
	// the encryption configuration for ad serving or Data Transfer.
	//
	// Possible values:
	//   "ADWORDS_CUSTOMER"
	//   "DBM_ADVERTISER"
	//   "DBM_PARTNER"
	//   "DCM_ACCOUNT"
	//   "DCM_ADVERTISER"
	//   "ENCRYPTION_ENTITY_TYPE_UNKNOWN"
	EncryptionEntityType string `json:"encryptionEntityType,omitempty"`

	// EncryptionSource: Describes whether the encrypted cookie was received
	// from ad serving (the %m macro) or from Data Transfer.
	//
	// Possible values:
	//   "AD_SERVING"
	//   "DATA_TRANSFER"
	//   "ENCRYPTION_SCOPE_UNKNOWN"
	EncryptionSource string `json:"encryptionSource,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "EncryptionEntityId")
	// 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:"-"`

	// NullFields is a list of field names (e.g. "EncryptionEntityId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// ExcludeFromAdxRequests: Whether to remove this event tag from ads
	// that are trafficked through DoubleClick Bid Manager to Ad Exchange.
	// This may be useful if the event tag uses a pixel that is unapproved
	// for Ad Exchange bids on one or more networks, such as the Google
	// Display Network.
	ExcludeFromAdxRequests bool `json:"excludeFromAdxRequests,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Enabled") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "EventTags") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DateRange") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ApiUrl") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Flight: Flight
type Flight struct {
	// EndDate: Inventory item flight end date.
	EndDate string `json:"endDate,omitempty"`

	// RateOrCost: Rate or cost of this flight.
	RateOrCost int64 `json:"rateOrCost,omitempty,string"`

	// StartDate: Inventory item flight start date.
	StartDate string `json:"startDate,omitempty"`

	// Units: Units of this flight.
	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:"-"`

	// NullFields is a list of field names (e.g. "EndDate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// FloodlightActivitiesGenerateTagResponse: Floodlight Activity
// GenerateTag Response
type FloodlightActivitiesGenerateTagResponse struct {
	// FloodlightActivityTag: Generated tag for this Floodlight activity.
	// For global site tags, this is the event snippet.
	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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightActivityTag") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightActivities") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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. Applicable only when floodlightActivityGroupType is COUNTER and
	// countingMethod is STANDARD_COUNTING or UNIQUE_COUNTING.
	//
	// 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= parameter 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-100]=" in the tags. Each
	// of these can have a user defined type.
	// Acceptable values are U1 to U100, inclusive.
	//
	// Possible values:
	//   "U1"
	//   "U10"
	//   "U100"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U2"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U3"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U4"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U5"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U6"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U7"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U8"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U9"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightActivityGroups")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ClickThrough") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// InAppAttributionTrackingEnabled: Whether in-app attribution tracking
	// is enabled.
	InAppAttributionTrackingEnabled bool `json:"inAppAttributionTrackingEnabled,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"`

	// 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"`

	// ThirdPartyAuthenticationTokens: List of third-party authentication
	// tokens enabled for this configuration.
	ThirdPartyAuthenticationTokens []*ThirdPartyAuthenticationToken `json:"thirdPartyAuthenticationTokens,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightConfigurations")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionFilters") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// FrequencyCap: Frequency Cap.
type FrequencyCap struct {
	// Duration: Duration of time, in seconds, for this frequency cap. The
	// maximum duration is 90 days. Acceptable values are 1 to 7776000,
	// inclusive.
	Duration int64 `json:"duration,omitempty,string"`

	// Impressions: Number of times an individual user can be served the ad
	// within the specified duration. Acceptable values are 1 to 15,
	// inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "Duration") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Left") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Cities") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// InventoryItem: Represents a buy from the DoubleClick Planning
// inventory store.
type InventoryItem struct {
	// AccountId: Account ID of this inventory item.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdSlots: Ad slots of this inventory item. If this inventory item
	// represents a standalone placement, there will be exactly one ad slot.
	// If this inventory item represents a placement group, there will be
	// more than one ad slot, each representing one child placement in that
	// placement group.
	AdSlots []*AdSlot `json:"adSlots,omitempty"`

	// AdvertiserId: Advertiser ID of this inventory item.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// ContentCategoryId: Content category ID of this inventory item.
	ContentCategoryId int64 `json:"contentCategoryId,omitempty,string"`

	// EstimatedClickThroughRate: Estimated click-through rate of this
	// inventory item.
	EstimatedClickThroughRate int64 `json:"estimatedClickThroughRate,omitempty,string"`

	// EstimatedConversionRate: Estimated conversion rate of this inventory
	// item.
	EstimatedConversionRate int64 `json:"estimatedConversionRate,omitempty,string"`

	// Id: ID of this inventory item.
	Id int64 `json:"id,omitempty,string"`

	// InPlan: Whether this inventory item is in plan.
	InPlan bool `json:"inPlan,omitempty"`

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

	// LastModifiedInfo: Information about the most recent modification of
	// this inventory item.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

	// Name: Name of this inventory item. For standalone inventory items,
	// this is the same name as that of its only ad slot. For group
	// inventory items, this can differ from the name of any of its ad
	// slots.
	Name string `json:"name,omitempty"`

	// NegotiationChannelId: Negotiation channel ID of this inventory item.
	NegotiationChannelId int64 `json:"negotiationChannelId,omitempty,string"`

	// OrderId: Order ID of this inventory item.
	OrderId int64 `json:"orderId,omitempty,string"`

	// PlacementStrategyId: Placement strategy ID of this inventory item.
	PlacementStrategyId int64 `json:"placementStrategyId,omitempty,string"`

	// Pricing: Pricing of this inventory item.
	Pricing *Pricing `json:"pricing,omitempty"`

	// ProjectId: Project ID of this inventory item.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// RfpId: RFP ID of this inventory item.
	RfpId int64 `json:"rfpId,omitempty,string"`

	// SiteId: ID of the site this inventory item is associated with.
	SiteId int64 `json:"siteId,omitempty,string"`

	// SubaccountId: Subaccount ID of this inventory item.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Type: Type of inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_TYPE_CREDIT"
	//   "PLANNING_PLACEMENT_TYPE_REGULAR"
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// InventoryItemsListResponse: Inventory item List Response
type InventoryItemsListResponse struct {
	// InventoryItems: Inventory item collection
	InventoryItems []*InventoryItem `json:"inventoryItems,omitempty"`

	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#inventoryItemsListResponse".
	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. "InventoryItems") 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:"-"`

	// NullFields is a list of field names (e.g. "InventoryItems") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Expression") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Default") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Language: Contains information about a language that can be targeted
// by ads.
type Language struct {
	// Id: Language ID of this language. This is the ID used for targeting
	// and generating reports.
	Id int64 `json:"id,omitempty,string"`

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

	// LanguageCode: Format of language code is an ISO 639 two-letter
	// language code optionally followed by an underscore followed by an ISO
	// 3166 code. Examples are "en" for English or "zh_CN" for Simplified
	// Chinese.
	LanguageCode string `json:"languageCode,omitempty"`

	// Name: Name of this language.
	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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// LanguageTargeting: Language Targeting.
type LanguageTargeting struct {
	// Languages: Languages that this ad targets. For each language only
	// languageId is required. The other fields are populated automatically
	// when the ad is inserted or updated.
	Languages []*Language `json:"languages,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Languages") 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:"-"`

	// NullFields is a list of field names (e.g. "Languages") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// LanguagesListResponse: Language List Response
type LanguagesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#languagesListResponse".
	Kind string `json:"kind,omitempty"`

	// Languages: Language collection.
	Languages []*Language `json:"languages,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Time") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ListPopulationClause: A group clause made up of list population terms
// representing constraints joined by ORs.
type ListPopulationClause struct {
	// Terms: Terms of this list population clause. Each clause is made up
	// of list population terms representing constraints and are joined by
	// ORs.
	Terms []*ListPopulationTerm `json:"terms,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Terms") 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:"-"`

	// NullFields is a list of field names (e.g. "Terms") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ListPopulationRule: Remarketing List Population Rule.
type ListPopulationRule struct {
	// FloodlightActivityId: Floodlight activity ID associated with this
	// rule. This field can be left blank.
	FloodlightActivityId int64 `json:"floodlightActivityId,omitempty,string"`

	// FloodlightActivityName: Name of floodlight activity associated with
	// this rule. This is a read-only, auto-generated field.
	FloodlightActivityName string `json:"floodlightActivityName,omitempty"`

	// ListPopulationClauses: Clauses that make up this list population
	// rule. Clauses are joined by ANDs, and the clauses themselves are made
	// up of list population terms which are joined by ORs.
	ListPopulationClauses []*ListPopulationClause `json:"listPopulationClauses,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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightActivityId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// ListPopulationTerm: Remarketing List Population Rule Term.
type ListPopulationTerm struct {
	// Contains: Will be true if the term should check if the user is in the
	// list and false if the term should check if the user is not in the
	// list. This field is only relevant when type is set to
	// LIST_MEMBERSHIP_TERM. False by default.
	Contains bool `json:"contains,omitempty"`

	// Negation: Whether to negate the comparison result of this term during
	// rule evaluation. This field is only relevant when type is left unset
	// or set to CUSTOM_VARIABLE_TERM or REFERRER_TERM.
	Negation bool `json:"negation,omitempty"`

	// Operator: Comparison operator of this term. This field is only
	// relevant when type is left unset or set to CUSTOM_VARIABLE_TERM or
	// REFERRER_TERM.
	//
	// Possible values:
	//   "NUM_EQUALS"
	//   "NUM_GREATER_THAN"
	//   "NUM_GREATER_THAN_EQUAL"
	//   "NUM_LESS_THAN"
	//   "NUM_LESS_THAN_EQUAL"
	//   "STRING_CONTAINS"
	//   "STRING_EQUALS"
	Operator string `json:"operator,omitempty"`

	// RemarketingListId: ID of the list in question. This field is only
	// relevant when type is set to LIST_MEMBERSHIP_TERM.
	RemarketingListId int64 `json:"remarketingListId,omitempty,string"`

	// Type: List population term type determines the applicable fields in
	// this object. If left unset or set to CUSTOM_VARIABLE_TERM, then
	// variableName, variableFriendlyName, operator, value, and negation are
	// applicable. If set to LIST_MEMBERSHIP_TERM then remarketingListId and
	// contains are applicable. If set to REFERRER_TERM then operator,
	// value, and negation are applicable.
	//
	// Possible values:
	//   "CUSTOM_VARIABLE_TERM"
	//   "LIST_MEMBERSHIP_TERM"
	//   "REFERRER_TERM"
	Type string `json:"type,omitempty"`

	// Value: Literal to compare the variable to. This field is only
	// relevant when type is left unset or set to CUSTOM_VARIABLE_TERM or
	// REFERRER_TERM.
	Value string `json:"value,omitempty"`

	// VariableFriendlyName: Friendly name of this term's variable. This is
	// a read-only, auto-generated field. This field is only relevant when
	// type is left unset or set to CUSTOM_VARIABLE_TERM.
	VariableFriendlyName string `json:"variableFriendlyName,omitempty"`

	// VariableName: Name of the variable (U1, U2, etc.) being compared in
	// this term. This field is only relevant when type is set to null,
	// CUSTOM_VARIABLE_TERM or REFERRER_TERM.
	VariableName string `json:"variableName,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Contains") 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:"-"`

	// NullFields is a list of field names (e.g. "Contains") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Expression") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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.
	// Acceptable values are 0 to 90, inclusive.
	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. Acceptable values are 0 to 90,
	// inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "ClickDuration") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CountryCode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "CountryCode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Left") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "OmnitureCostDataEnabled")
	// to include in API requests with the JSON null value. By default,
	// fields with empty values are omitted from API requests. However, any
	// field with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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"`

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

	// 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:"-"`

	// NullFields is a list of field names (e.g. "DartId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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. The weight assigned
	// will be understood in proportion to the weights assigned to the other
	// optimization activities. Value must be greater than or equal to 1.
	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:"-"`

	// NullFields is a list of field names (e.g. "FloodlightActivityId") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// Order: Describes properties of a DoubleClick Planning order.
type Order struct {
	// AccountId: Account ID of this order.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this order.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// ApproverUserProfileIds: IDs for users that have to approve documents
	// created for this order.
	ApproverUserProfileIds googleapi.Int64s `json:"approverUserProfileIds,omitempty"`

	// BuyerInvoiceId: Buyer invoice ID associated with this order.
	BuyerInvoiceId string `json:"buyerInvoiceId,omitempty"`

	// BuyerOrganizationName: Name of the buyer organization.
	BuyerOrganizationName string `json:"buyerOrganizationName,omitempty"`

	// Comments: Comments in this order.
	Comments string `json:"comments,omitempty"`

	// Contacts: Contacts for this order.
	Contacts []*OrderContact `json:"contacts,omitempty"`

	// Id: ID of this order. 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#order".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this order.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

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

	// Notes: Notes of this order.
	Notes string `json:"notes,omitempty"`

	// PlanningTermId: ID of the terms and conditions template used in this
	// order.
	PlanningTermId int64 `json:"planningTermId,omitempty,string"`

	// ProjectId: Project ID of this order.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// SellerOrderId: Seller order ID associated with this order.
	SellerOrderId string `json:"sellerOrderId,omitempty"`

	// SellerOrganizationName: Name of the seller organization.
	SellerOrganizationName string `json:"sellerOrganizationName,omitempty"`

	// SiteId: Site IDs this order is associated with.
	SiteId googleapi.Int64s `json:"siteId,omitempty"`

	// SiteNames: Free-form site names this order is associated with.
	SiteNames []string `json:"siteNames,omitempty"`

	// SubaccountId: Subaccount ID of this order.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TermsAndConditions: Terms and conditions of this order.
	TermsAndConditions string `json:"termsAndConditions,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// OrderContact: Contact of an order.
type OrderContact struct {
	// ContactInfo: Free-form information about this contact. It could be
	// any information related to this contact in addition to type, title,
	// name, and signature user profile ID.
	ContactInfo string `json:"contactInfo,omitempty"`

	// ContactName: Name of this contact.
	ContactName string `json:"contactName,omitempty"`

	// ContactTitle: Title of this contact.
	ContactTitle string `json:"contactTitle,omitempty"`

	// ContactType: Type of this contact.
	//
	// Possible values:
	//   "PLANNING_ORDER_CONTACT_BUYER_BILLING_CONTACT"
	//   "PLANNING_ORDER_CONTACT_BUYER_CONTACT"
	//   "PLANNING_ORDER_CONTACT_SELLER_CONTACT"
	ContactType string `json:"contactType,omitempty"`

	// SignatureUserProfileId: ID of the user profile containing the
	// signature that will be embedded into order documents.
	SignatureUserProfileId int64 `json:"signatureUserProfileId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "ContactInfo") 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:"-"`

	// NullFields is a list of field names (e.g. "ContactInfo") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// OrderDocument: Contains properties of a DoubleClick Planning order
// document.
type OrderDocument struct {
	// AccountId: Account ID of this order document.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this order document.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AmendedOrderDocumentId: The amended order document ID of this order
	// document. An order document can be created by optionally amending
	// another order document so that the change history can be preserved.
	AmendedOrderDocumentId int64 `json:"amendedOrderDocumentId,omitempty,string"`

	// ApprovedByUserProfileIds: IDs of users who have approved this order
	// document.
	ApprovedByUserProfileIds googleapi.Int64s `json:"approvedByUserProfileIds,omitempty"`

	// Cancelled: Whether this order document is cancelled.
	Cancelled bool `json:"cancelled,omitempty"`

	// CreatedInfo: Information about the creation of this order document.
	CreatedInfo *LastModifiedInfo `json:"createdInfo,omitempty"`

	// EffectiveDate: Effective date of this order document.
	EffectiveDate string `json:"effectiveDate,omitempty"`

	// Id: ID of this order document.
	Id int64 `json:"id,omitempty,string"`

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

	// LastSentRecipients: List of email addresses that received the last
	// sent document.
	LastSentRecipients []string `json:"lastSentRecipients,omitempty"`

	// LastSentTime: Timestamp of the last email sent with this order
	// document.
	LastSentTime string `json:"lastSentTime,omitempty"`

	// OrderId: ID of the order from which this order document is created.
	OrderId int64 `json:"orderId,omitempty,string"`

	// ProjectId: Project ID of this order document.
	ProjectId int64 `json:"projectId,omitempty,string"`

	// Signed: Whether this order document has been signed.
	Signed bool `json:"signed,omitempty"`

	// SubaccountId: Subaccount ID of this order document.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// Title: Title of this order document.
	Title string `json:"title,omitempty"`

	// Type: Type of this order document
	//
	// Possible values:
	//   "PLANNING_ORDER_TYPE_CHANGE_ORDER"
	//   "PLANNING_ORDER_TYPE_INSERTION_ORDER"
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// OrderDocumentsListResponse: Order document List Response
type OrderDocumentsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#orderDocumentsListResponse".
	Kind string `json:"kind,omitempty"`

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

	// OrderDocuments: Order document collection
	OrderDocuments []*OrderDocument `json:"orderDocuments,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// OrdersListResponse: Order List Response
type OrdersListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#ordersListResponse".
	Kind string `json:"kind,omitempty"`

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

	// Orders: Order collection.
	Orders []*Order `json:"orders,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ConversionDimensions") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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. DISPLAY and
	// DISPLAY_INTERSTITIAL refer to rendering on desktop, on mobile devices
	// or in mobile apps for regular or interstitial ads respectively. APP
	// and APP_INTERSTITIAL are no longer allowed for new placement
	// insertions. Instead, use DISPLAY or DISPLAY_INTERSTITIAL.
	// 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"
	//   "DISPLAY"
	//   "DISPLAY_INTERSTITIAL"
	//   "IN_STREAM_VIDEO"
	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_INSTREAM_VIDEO_PREFETCH_VAST_3"
	// - "PLACEMENT_TAG_INSTREAM_VIDEO_PREFETCH_VAST_4"
	// - "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_INSTREAM_VIDEO_PREFETCH_VAST_4"
	//   "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"`

	// VideoActiveViewOptOut: Whether Verification and ActiveView are
	// disabled for in-stream video creatives for this placement. The same
	// setting videoActiveViewOptOut exists on the site level -- the opt out
	// occurs if either of these settings are true. These settings are
	// distinct from DirectorySites.settings.activeViewOptOut or
	// Sites.siteSettings.activeViewOptOut which only apply to display ads.
	// However, Accounts.activeViewOptOut opts out both video traffic, as
	// well as display ads, from Verification and ActiveView.
	VideoActiveViewOptOut bool `json:"videoActiveViewOptOut,omitempty"`

	// VideoSettings: A collection of settings which affect video creatives
	// served through this placement. Applicable to placements with
	// IN_STREAM_VIDEO compatibility.
	VideoSettings *VideoSettings `json:"videoSettings,omitempty"`

	// VpaidAdapterChoice: VPAID adapter setting for this placement.
	// Controls which VPAID format the measurement adapter will use for
	// in-stream video creatives assigned to this placement.
	//
	// Note: Flash is no longer supported. This field now defaults to HTML5
	// when the following values are provided: FLASH, BOTH.
	//
	// Possible values:
	//   "BOTH"
	//   "DEFAULT"
	//   "FLASH"
	//   "HTML5"
	VpaidAdapterChoice string `json:"vpaidAdapterChoice,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Active") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "PlacementId") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Dimension") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// PostalCode: Contains information about a postal code that can be
// targeted by ads.
type PostalCode struct {
	// Code: Postal code. This is equivalent to the id field.
	Code string `json:"code,omitempty"`

	// 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"`

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

	// ForceSendFields is a list of field names (e.g. "Code") 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:"-"`

	// NullFields is a list of field names (e.g. "Code") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Pricing: Pricing Information
type Pricing struct {
	// CapCostType: Cap cost type of this inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_CUMULATIVE"
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_MONTHLY"
	//   "PLANNING_PLACEMENT_CAP_COST_TYPE_NONE"
	CapCostType string `json:"capCostType,omitempty"`

	// EndDate: End date of this inventory item.
	EndDate string `json:"endDate,omitempty"`

	// Flights: Flights of this inventory item. A flight (a.k.a. pricing
	// period) represents the inventory item pricing information for a
	// specific period of time.
	Flights []*Flight `json:"flights,omitempty"`

	// GroupType: Group type of this inventory item if it represents a
	// placement group. Is null otherwise. There are two type of placement
	// groups: PLANNING_PLACEMENT_GROUP_TYPE_PACKAGE is a simple group of
	// inventory items that acts as a single pricing point for a group of
	// tags. PLANNING_PLACEMENT_GROUP_TYPE_ROADBLOCK is a group of inventory
	// items 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 inventory items to be marked as primary.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_GROUP_TYPE_PACKAGE"
	//   "PLANNING_PLACEMENT_GROUP_TYPE_ROADBLOCK"
	GroupType string `json:"groupType,omitempty"`

	// PricingType: Pricing type of this inventory item.
	//
	// Possible values:
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CLICKS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPA"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPC"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPM"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_CPM_ACTIVEVIEW"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_FLAT_RATE_CLICKS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_FLAT_RATE_IMPRESSIONS"
	//   "PLANNING_PLACEMENT_PRICING_TYPE_IMPRESSIONS"
	PricingType string `json:"pricingType,omitempty"`

	// StartDate: Start date of this inventory item.
	StartDate string `json:"startDate,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CapCostType") 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:"-"`

	// NullFields is a list of field names (e.g. "CapCostType") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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_CPM_ACTIVEVIEW"
	//   "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:"-"`

	// NullFields is a list of field names (e.g. "CapCostOption") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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 in nanos (i.e.,
	// multipled by 1000000000). Acceptable values are 0 to
	// 1000000000000000000, inclusive.
	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. Acceptable values are 0 to
	// 10000000000, inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "EndDate") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Project: Contains properties of a DoubleClick Planning project.
type Project struct {
	// AccountId: Account ID of this project.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this project.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AudienceAgeGroup: Audience age group of this project.
	//
	// Possible values:
	//   "PLANNING_AUDIENCE_AGE_18_24"
	//   "PLANNING_AUDIENCE_AGE_25_34"
	//   "PLANNING_AUDIENCE_AGE_35_44"
	//   "PLANNING_AUDIENCE_AGE_45_54"
	//   "PLANNING_AUDIENCE_AGE_55_64"
	//   "PLANNING_AUDIENCE_AGE_65_OR_MORE"
	//   "PLANNING_AUDIENCE_AGE_UNKNOWN"
	AudienceAgeGroup string `json:"audienceAgeGroup,omitempty"`

	// AudienceGender: Audience gender of this project.
	//
	// Possible values:
	//   "PLANNING_AUDIENCE_GENDER_FEMALE"
	//   "PLANNING_AUDIENCE_GENDER_MALE"
	AudienceGender string `json:"audienceGender,omitempty"`

	// Budget: Budget of this project in the currency specified by the
	// current account. The value stored in this field represents only the
	// non-fractional amount. For example, for USD, the smallest value that
	// can be represented by this field is 1 US dollar.
	Budget int64 `json:"budget,omitempty,string"`

	// ClientBillingCode: Client billing code of this project.
	ClientBillingCode string `json:"clientBillingCode,omitempty"`

	// ClientName: Name of the project client.
	ClientName string `json:"clientName,omitempty"`

	// EndDate: End date of the project.
	EndDate string `json:"endDate,omitempty"`

	// Id: ID of this project. 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#project".
	Kind string `json:"kind,omitempty"`

	// LastModifiedInfo: Information about the most recent modification of
	// this project.
	LastModifiedInfo *LastModifiedInfo `json:"lastModifiedInfo,omitempty"`

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

	// Overview: Overview of this project.
	Overview string `json:"overview,omitempty"`

	// StartDate: Start date of the project.
	StartDate string `json:"startDate,omitempty"`

	// SubaccountId: Subaccount ID of this project.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TargetClicks: Number of clicks that the advertiser is targeting.
	TargetClicks int64 `json:"targetClicks,omitempty,string"`

	// TargetConversions: Number of conversions that the advertiser is
	// targeting.
	TargetConversions int64 `json:"targetConversions,omitempty,string"`

	// TargetCpaNanos: CPA that the advertiser is targeting.
	TargetCpaNanos int64 `json:"targetCpaNanos,omitempty,string"`

	// TargetCpcNanos: CPC that the advertiser is targeting.
	TargetCpcNanos int64 `json:"targetCpcNanos,omitempty,string"`

	// TargetCpmActiveViewNanos: vCPM from Active View that the advertiser
	// is targeting.
	TargetCpmActiveViewNanos int64 `json:"targetCpmActiveViewNanos,omitempty,string"`

	// TargetCpmNanos: CPM that the advertiser is targeting.
	TargetCpmNanos int64 `json:"targetCpmNanos,omitempty,string"`

	// TargetImpressions: Number of impressions that the advertiser is
	// targeting.
	TargetImpressions int64 `json:"targetImpressions,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ProjectsListResponse: Project List Response
type ProjectsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#projectsListResponse".
	Kind string `json:"kind,omitempty"`

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

	// Projects: Project collection.
	Projects []*Project `json:"projects,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionFilters") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DeliveryType") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CountryCode") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// RemarketingList: Contains properties of a remarketing list.
// Remarketing enables you to create lists of users who have performed
// specific actions on a site, then target ads to members of those
// lists. This resource can be used to manage remarketing lists that are
// owned by your advertisers. To see all remarketing lists that are
// visible to your advertisers, including those that are shared to your
// advertiser or account, use the TargetableRemarketingLists resource.
type RemarketingList struct {
	// AccountId: Account ID of this remarketing list. This is a read-only,
	// auto-generated field that is only returned in GET requests.
	AccountId int64 `json:"accountId,omitempty,string"`

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

	// AdvertiserId: Dimension value for the advertiser ID that owns this
	// remarketing list. This is a required field.
	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"`

	// Description: Remarketing list description.
	Description string `json:"description,omitempty"`

	// Id: Remarketing list ID. 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#remarketingList".
	Kind string `json:"kind,omitempty"`

	// LifeSpan: Number of days that a user should remain in the remarketing
	// list without an impression. Acceptable values are 1 to 540,
	// inclusive.
	LifeSpan int64 `json:"lifeSpan,omitempty,string"`

	// ListPopulationRule: Rule used to populate the remarketing list with
	// users.
	ListPopulationRule *ListPopulationRule `json:"listPopulationRule,omitempty"`

	// ListSize: Number of users currently in the list. This is a read-only
	// field.
	ListSize int64 `json:"listSize,omitempty,string"`

	// ListSource: Product from which this remarketing list was originated.
	//
	// Possible values:
	//   "REMARKETING_LIST_SOURCE_ADX"
	//   "REMARKETING_LIST_SOURCE_DBM"
	//   "REMARKETING_LIST_SOURCE_DFA"
	//   "REMARKETING_LIST_SOURCE_DFP"
	//   "REMARKETING_LIST_SOURCE_DMP"
	//   "REMARKETING_LIST_SOURCE_GA"
	//   "REMARKETING_LIST_SOURCE_GPLUS"
	//   "REMARKETING_LIST_SOURCE_OTHER"
	//   "REMARKETING_LIST_SOURCE_PLAY_STORE"
	//   "REMARKETING_LIST_SOURCE_XFP"
	//   "REMARKETING_LIST_SOURCE_YOUTUBE"
	ListSource string `json:"listSource,omitempty"`

	// Name: Name of the remarketing list. This is a required field. Must be
	// no greater than 128 characters long.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this remarketing list. This is a
	// read-only, auto-generated field that is only returned in GET
	// requests.
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// RemarketingListShare: Contains properties of a remarketing list's
// sharing information. Sharing allows other accounts or advertisers to
// target to your remarketing lists. This resource can be used to manage
// remarketing list sharing to other accounts and advertisers.
type RemarketingListShare struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#remarketingListShare".
	Kind string `json:"kind,omitempty"`

	// RemarketingListId: Remarketing list ID. This is a read-only,
	// auto-generated field.
	RemarketingListId int64 `json:"remarketingListId,omitempty,string"`

	// SharedAccountIds: Accounts that the remarketing list is shared with.
	SharedAccountIds googleapi.Int64s `json:"sharedAccountIds,omitempty"`

	// SharedAdvertiserIds: Advertisers that the remarketing list is shared
	// with.
	SharedAdvertiserIds googleapi.Int64s `json:"sharedAdvertiserIds,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// RemarketingListsListResponse: Remarketing list response
type RemarketingListsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#remarketingListsListResponse".
	Kind string `json:"kind,omitempty"`

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

	// RemarketingLists: Remarketing list collection.
	RemarketingLists []*RemarketingList `json:"remarketingLists,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Activities") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Breakdown") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "EmailOwner") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CustomRichMediaEvents") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g.
	// "IncludeAttributedIPConversions") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ActivityFilters") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ClicksLookbackWindow") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Activities") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Active") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DimensionFilters") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g.
	// "ExposureToConversionEnabled") to include in API requests with the
	// JSON null value. By default, fields with empty values are omitted
	// from API requests. However, any field with an empty value appearing
	// in NullFields will be sent to the server as null. It is an error if a
	// field in this list has a non-empty value. This may be used to include
	// null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// RichMediaExitOverride: Rich Media Exit Override.
type RichMediaExitOverride struct {
	// ClickThroughUrl: Click-through URL of this rich media exit override.
	// Applicable if the enabled field is set to true.
	ClickThroughUrl *ClickThroughUrl `json:"clickThroughUrl,omitempty"`

	// Enabled: Whether to use the clickThroughUrl. If false, the
	// creative-level exit will be used.
	Enabled bool `json:"enabled,omitempty"`

	// ExitId: ID for the override to refer to a specific exit in the
	// creative.
	ExitId int64 `json:"exitId,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:"-"`

	// NullFields is a list of field names (e.g. "ClickThroughUrl") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// Rule: A rule associates an asset with a targeting template for
// asset-level targeting. Applicable to INSTREAM_VIDEO creatives.
type Rule struct {
	// AssetId: A creativeAssets[].id. This should refer to one of the
	// parent assets in this creative. This is a required field.
	AssetId int64 `json:"assetId,omitempty,string"`

	// Name: A user-friendly name for this rule. This is a required field.
	Name string `json:"name,omitempty"`

	// TargetingTemplateId: A targeting template ID. The targeting from the
	// targeting template will be used to determine whether this asset
	// should be served. This is a required field.
	TargetingTemplateId int64 `json:"targetingTemplateId,omitempty,string"`

	// ForceSendFields is a list of field names (e.g. "AssetId") 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:"-"`

	// NullFields is a list of field names (e.g. "AssetId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// SiteContact: Site Contact
type SiteContact struct {
	// Address: Address of this site contact.
	Address string `json:"address,omitempty"`

	// 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"`

	// Phone: Primary phone number of this site contact.
	Phone string `json:"phone,omitempty"`

	// Title: Title or designation of this site contact.
	Title string `json:"title,omitempty"`

	// ForceSendFields is a list of field names (e.g. "Address") 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:"-"`

	// NullFields is a list of field names (e.g. "Address") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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"`

	// VideoActiveViewOptOutTemplate: Whether Verification and ActiveView
	// for in-stream video creatives are disabled by default for new
	// placements created under this site. This value will be used to
	// populate the placement.videoActiveViewOptOut field, when no value is
	// specified for the new placement.
	VideoActiveViewOptOutTemplate bool `json:"videoActiveViewOptOutTemplate,omitempty"`

	// VpaidAdapterChoiceTemplate: Default VPAID adapter setting for new
	// placements created under this site. This value will be used to
	// populate the placements.vpaidAdapterChoice field, when no value is
	// specified for the new placement. Controls which VPAID format the
	// measurement adapter will use for in-stream video creatives assigned
	// to the placement. The publisher's specifications will typically
	// determine this setting. For VPAID creatives, the adapter format will
	// match the VPAID format (HTML5 VPAID creatives use the HTML5
	// adapter).
	//
	// Note: Flash is no longer supported. This field now defaults to HTML5
	// when the following values are provided: FLASH, BOTH.
	//
	// Possible values:
	//   "BOTH"
	//   "DEFAULT"
	//   "FLASH"
	//   "HTML5"
	VpaidAdapterChoiceTemplate string `json:"vpaidAdapterChoiceTemplate,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:"-"`

	// NullFields is a list of field names (e.g. "ActiveViewOptOut") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// Size: Represents the dimensions of ads, placements, creatives, or
// creative assets.
type Size struct {
	// Height: Height of this size. Acceptable values are 0 to 32767,
	// inclusive.
	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. Acceptable values are 0 to 32767,
	// inclusive.
	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:"-"`

	// NullFields is a list of field names (e.g. "Height") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// SkippableSetting: Skippable Settings
type SkippableSetting struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#skippableSetting".
	Kind string `json:"kind,omitempty"`

	// ProgressOffset: Amount of time to play videos served to this
	// placement before counting a view. Applicable when skippable is true.
	ProgressOffset *VideoOffset `json:"progressOffset,omitempty"`

	// SkipOffset: Amount of time to play videos served to this placement
	// before the skip button should appear. Applicable when skippable is
	// true.
	SkipOffset *VideoOffset `json:"skipOffset,omitempty"`

	// Skippable: Whether the user can skip creatives served to this
	// placement.
	Skippable bool `json:"skippable,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// TagData: Placement Tag Data
type TagData struct {
	// AdId: Ad associated with this placement tag. Applicable only when
	// format is PLACEMENT_TAG_TRACKING.
	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. Applicable
	// only when format is PLACEMENT_TAG_TRACKING.
	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_INSTREAM_VIDEO_PREFETCH_VAST_4"
	//   "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:"-"`

	// NullFields is a list of field names (e.g. "AdId") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AdditionalKeyValues") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "DynamicTagEnabled") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "CustomHtml") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// TargetableRemarketingList: Contains properties of a targetable
// remarketing list. Remarketing enables you to create lists of users
// who have performed specific actions on a site, then target ads to
// members of those lists. This resource is a read-only view of a
// remarketing list to be used to faciliate targeting ads to specific
// lists. Remarketing lists that are owned by your advertisers and those
// that are shared to your advertisers or account are accessible via
// this resource. To manage remarketing lists that are owned by your
// advertisers, use the RemarketingLists resource.
type TargetableRemarketingList struct {
	// AccountId: Account ID of this remarketing list. This is a read-only,
	// auto-generated field that is only returned in GET requests.
	AccountId int64 `json:"accountId,omitempty,string"`

	// Active: Whether this targetable remarketing list is active.
	Active bool `json:"active,omitempty"`

	// AdvertiserId: Dimension value for the advertiser ID that owns this
	// targetable remarketing list.
	AdvertiserId int64 `json:"advertiserId,omitempty,string"`

	// AdvertiserIdDimensionValue: Dimension value for the ID of the
	// advertiser.
	AdvertiserIdDimensionValue *DimensionValue `json:"advertiserIdDimensionValue,omitempty"`

	// Description: Targetable remarketing list description.
	Description string `json:"description,omitempty"`

	// Id: Targetable remarketing list ID.
	Id int64 `json:"id,omitempty,string"`

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

	// LifeSpan: Number of days that a user should remain in the targetable
	// remarketing list without an impression.
	LifeSpan int64 `json:"lifeSpan,omitempty,string"`

	// ListSize: Number of users currently in the list. This is a read-only
	// field.
	ListSize int64 `json:"listSize,omitempty,string"`

	// ListSource: Product from which this targetable remarketing list was
	// originated.
	//
	// Possible values:
	//   "REMARKETING_LIST_SOURCE_ADX"
	//   "REMARKETING_LIST_SOURCE_DBM"
	//   "REMARKETING_LIST_SOURCE_DFA"
	//   "REMARKETING_LIST_SOURCE_DFP"
	//   "REMARKETING_LIST_SOURCE_DMP"
	//   "REMARKETING_LIST_SOURCE_GA"
	//   "REMARKETING_LIST_SOURCE_GPLUS"
	//   "REMARKETING_LIST_SOURCE_OTHER"
	//   "REMARKETING_LIST_SOURCE_PLAY_STORE"
	//   "REMARKETING_LIST_SOURCE_XFP"
	//   "REMARKETING_LIST_SOURCE_YOUTUBE"
	ListSource string `json:"listSource,omitempty"`

	// Name: Name of the targetable remarketing list. Is no greater than 128
	// characters long.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this remarketing list. This is a
	// read-only, auto-generated field that is only returned in GET
	// requests.
	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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// TargetableRemarketingListsListResponse: Targetable remarketing list
// response
type TargetableRemarketingListsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetableRemarketingListsListResponse".
	Kind string `json:"kind,omitempty"`

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

	// TargetableRemarketingLists: Targetable remarketing list collection.
	TargetableRemarketingLists []*TargetableRemarketingList `json:"targetableRemarketingLists,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// TargetingTemplate: Contains properties of a targeting template. A
// targeting template encapsulates targeting information which can be
// reused across multiple ads.
type TargetingTemplate struct {
	// AccountId: Account ID of this targeting template. This field, if left
	// unset, will be auto-generated on insert and is read-only after
	// insert.
	AccountId int64 `json:"accountId,omitempty,string"`

	// AdvertiserId: Advertiser ID of this targeting template. This is a
	// required field on insert and is read-only after insert.
	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"`

	// DayPartTargeting: Time and day targeting criteria.
	DayPartTargeting *DayPartTargeting `json:"dayPartTargeting,omitempty"`

	// GeoTargeting: Geographical targeting criteria.
	GeoTargeting *GeoTargeting `json:"geoTargeting,omitempty"`

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

	// KeyValueTargetingExpression: Key-value targeting criteria.
	KeyValueTargetingExpression *KeyValueTargetingExpression `json:"keyValueTargetingExpression,omitempty"`

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

	// LanguageTargeting: Language targeting criteria.
	LanguageTargeting *LanguageTargeting `json:"languageTargeting,omitempty"`

	// ListTargetingExpression: Remarketing list targeting criteria.
	ListTargetingExpression *ListTargetingExpression `json:"listTargetingExpression,omitempty"`

	// Name: Name of this targeting template. This field is required. It
	// must be less than 256 characters long and unique within an
	// advertiser.
	Name string `json:"name,omitempty"`

	// SubaccountId: Subaccount ID of this targeting template. This field,
	// if left unset, will be auto-generated on insert and is read-only
	// after insert.
	SubaccountId int64 `json:"subaccountId,omitempty,string"`

	// TechnologyTargeting: Technology platform targeting criteria.
	TechnologyTargeting *TechnologyTargeting `json:"technologyTargeting,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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// TargetingTemplatesListResponse: Targeting Template List Response
type TargetingTemplatesListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#targetingTemplatesListResponse".
	Kind string `json:"kind,omitempty"`

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

	// TargetingTemplates: Targeting template collection.
	TargetingTemplates []*TargetingTemplate `json:"targetingTemplates,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Browsers") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// ThirdPartyAuthenticationToken: Third Party Authentication Token
type ThirdPartyAuthenticationToken struct {
	// Name: Name of the third-party authentication token.
	Name string `json:"name,omitempty"`

	// Value: Value of the third-party authentication token. This is a
	// read-only, auto-generated field.
	Value string `json:"value,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:"-"`

	// NullFields is a list of field names (e.g. "Name") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "ThirdPartyUrlType") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// TranscodeSetting: Transcode Settings
type TranscodeSetting struct {
	// EnabledVideoFormats: Whitelist of video formats to be served to this
	// placement. Set this list to null or empty to serve all video formats.
	EnabledVideoFormats []int64 `json:"enabledVideoFormats,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "EnabledVideoFormats")
	// 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:"-"`

	// NullFields is a list of field names (e.g. "EnabledVideoFormats") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// 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"
	//   "U100"
	//   "U11"
	//   "U12"
	//   "U13"
	//   "U14"
	//   "U15"
	//   "U16"
	//   "U17"
	//   "U18"
	//   "U19"
	//   "U2"
	//   "U20"
	//   "U21"
	//   "U22"
	//   "U23"
	//   "U24"
	//   "U25"
	//   "U26"
	//   "U27"
	//   "U28"
	//   "U29"
	//   "U3"
	//   "U30"
	//   "U31"
	//   "U32"
	//   "U33"
	//   "U34"
	//   "U35"
	//   "U36"
	//   "U37"
	//   "U38"
	//   "U39"
	//   "U4"
	//   "U40"
	//   "U41"
	//   "U42"
	//   "U43"
	//   "U44"
	//   "U45"
	//   "U46"
	//   "U47"
	//   "U48"
	//   "U49"
	//   "U5"
	//   "U50"
	//   "U51"
	//   "U52"
	//   "U53"
	//   "U54"
	//   "U55"
	//   "U56"
	//   "U57"
	//   "U58"
	//   "U59"
	//   "U6"
	//   "U60"
	//   "U61"
	//   "U62"
	//   "U63"
	//   "U64"
	//   "U65"
	//   "U66"
	//   "U67"
	//   "U68"
	//   "U69"
	//   "U7"
	//   "U70"
	//   "U71"
	//   "U72"
	//   "U73"
	//   "U74"
	//   "U75"
	//   "U76"
	//   "U77"
	//   "U78"
	//   "U79"
	//   "U8"
	//   "U80"
	//   "U81"
	//   "U82"
	//   "U83"
	//   "U84"
	//   "U85"
	//   "U86"
	//   "U87"
	//   "U88"
	//   "U89"
	//   "U9"
	//   "U90"
	//   "U91"
	//   "U92"
	//   "U93"
	//   "U94"
	//   "U95"
	//   "U96"
	//   "U97"
	//   "U98"
	//   "U99"
	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:"-"`

	// NullFields is a list of field names (e.g. "DataType") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Etag") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "AccountId") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Availability") to include
	// in API requests with the JSON null value. By default, fields with
	// empty values are omitted from API requests. However, any field with
	// an empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Id") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// 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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// VideoFormat: Contains information about supported video formats.
type VideoFormat struct {
	// FileType: File type of the video format.
	//
	// Possible values:
	//   "FLV"
	//   "M3U8"
	//   "MP4"
	//   "THREEGPP"
	//   "WEBM"
	FileType string `json:"fileType,omitempty"`

	// Id: ID of the video format.
	Id int64 `json:"id,omitempty"`

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

	// Resolution: The resolution of this video format.
	Resolution *Size `json:"resolution,omitempty"`

	// TargetBitRate: The target bit rate of this video format.
	TargetBitRate int64 `json:"targetBitRate,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "FileType") 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:"-"`

	// NullFields is a list of field names (e.g. "FileType") to include in
	// API requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// VideoFormatsListResponse: Video Format List Response
type VideoFormatsListResponse struct {
	// Kind: Identifies what kind of resource this is. Value: the fixed
	// string "dfareporting#videoFormatsListResponse".
	Kind string `json:"kind,omitempty"`

	// VideoFormats: Video format collection.
	VideoFormats []*VideoFormat `json:"videoFormats,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:"-"`

	// NullFields is a list of field names (e.g. "Kind") to include in API
	// requests with the JSON null value. By default, fields with empty
	// values are omitted from API requests. However, any field with an
	// empty value appearing in NullFields will be sent to the server as
	// null. It is an error if a field in this list has a non-empty value.
	// This may be used to include null fields in Patch requests.
	NullFields []string `json:"-"`
}

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

// VideoOffset: Video Offset
type VideoOffset struct {
	// OffsetPercentage: Duration, as a percentage of video duration. Do not
	// set when offsetSeconds is set. Acceptable values are 0 to 100,
	// inclusive.
	OffsetPercentage int64 `json:"offsetPercentage,omitempty"`

	// OffsetSeconds: Duration, in seconds. Do not set when offsetPercentage
	// is set. Acceptable values are 0 to 86399, inclusive.
	OffsetSeconds int64 `json:"offsetSeconds,omitempty"`

	// ForceSendFields is a list of field names (e.g. "OffsetPercentage") 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:"-"`

	// NullFields is a list of field names (e.g. "OffsetPercentage") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// VideoSettings: Video Settings
type VideoSettings struct {
	// CompanionSettings: Settings for the companion creatives of video
	// creatives served to this placement.
	CompanionSettings *CompanionSetting `json:"companionSettings,omitempty"`

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

	// SkippableSettings: Settings for the skippability of video creatives
	// served to this placement. If this object is provided, the
	// creative-level skippable settings will be overridden.
	SkippableSettings *SkippableSetting `json:"skippableSettings,omitempty"`

	// TranscodeSettings: Settings for the transcodes of video creatives
	// served to this placement. If this object is provided, the
	// creative-level transcode settings will be overridden.
	TranscodeSettings *TranscodeSetting `json:"transcodeSettings,omitempty"`

	// ForceSendFields is a list of field names (e.g. "CompanionSettings")
	// 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:"-"`

	// NullFields is a list of field names (e.g. "CompanionSettings") to
	// include in API requests with the JSON null value. By default, fields
	// with empty values are omitted from API requests. However, any field
	// with an empty value appearing in NullFields will be sent to the
	// server as null. It is an error if a field in this list has a
	// non-empty value. This may be used to include null fields in Patch
	// requests.
	NullFields []string `json:"-"`
}

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

// method id "dfareporting.accountActiveAdSummaries.get":

type AccountActiveAdSummariesGetCall struct {
	s                *Service
	profileId        int64
	summaryAccountId int64
	urlParams_       gensupport.URLParams
	ifNoneMatch_     string
	ctx_             context.Context
	header_          http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountActiveAdSummariesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountActiveAdSummariesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountPermissionGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountPermissionGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountPermissionGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountPermissionGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountPermissionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountPermissionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountPermissionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountPermissionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountUserProfilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountUserProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.insert":

type AccountUserProfilesInsertCall struct {
	s                  *Service
	profileId          int64
	accountuserprofile *AccountUserProfile
	urlParams_         gensupport.URLParams
	ctx_               context.Context
	header_            http.Header
}

// Insert: Inserts a new account user profile.
func (r *AccountUserProfilesService) Insert(profileId int64, accountuserprofile *AccountUserProfile) *AccountUserProfilesInsertCall {
	c := &AccountUserProfilesInsertCall{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 *AccountUserProfilesInsertCall) Fields(s ...googleapi.Field) *AccountUserProfilesInsertCall {
	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 *AccountUserProfilesInsertCall) Context(ctx context.Context) *AccountUserProfilesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountUserProfilesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountUserProfilesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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("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.accountUserProfiles.insert" 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 *AccountUserProfilesInsertCall) 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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new account user profile.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.accountUserProfiles.insert",
	//   "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.accountUserProfiles.list":

type AccountUserProfilesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of account user profiles, possibly filtered.
// This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountUserProfilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountUserProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of account user profiles, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountUserProfilesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountUserProfilesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountUserProfilesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountUserProfilesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves the list of accounts, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of accounts, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AccountsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of ads, possibly filtered. This method
// supports paging.
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. DISPLAY and DISPLAY_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"
//   "DISPLAY"
//   "DISPLAY_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
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
}

// 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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of ads, possibly filtered. This method supports paging.",
	//   "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. DISPLAY and DISPLAY_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",
	//         "DISPLAY",
	//         "DISPLAY_INTERSTITIAL",
	//         "IN_STREAM_VIDEO"
	//       ],
	//       "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"
	//     },
	//     "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of advertiser groups, possibly filtered. This
// method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertiser groups, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertiserGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertiserGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertisersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertisersInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of advertisers, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertisersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of advertisers, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertisersPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *AdvertisersUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *AdvertisersUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *BrowsersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *BrowsersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_                     http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignCreativeAssociationsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignCreativeAssociationsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves the list of creative IDs associated with the
// specified campaign. This method supports paging.
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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignCreativeAssociationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignCreativeAssociationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves the list of creative IDs associated with the specified campaign. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of campaigns, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of campaigns, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CampaignsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CampaignsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ChangeLogsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChangeLogsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of change logs. This method supports paging.
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_SEARCH_LIFT_STUDY"
//   "OBJECT_SIZE"
//   "OBJECT_SUBACCOUNT"
//   "OBJECT_TARGETING_TEMPLATE"
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ChangeLogsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ChangeLogsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of change logs. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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_SEARCH_LIFT_STUDY",
	//         "OBJECT_SIZE",
	//         "OBJECT_SUBACCOUNT",
	//         "OBJECT_TARGETING_TEMPLATE",
	//         "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CitiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type ConnectionTypesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one connection type by ID.
func (r *ConnectionTypesService) Get(profileId int64, id int64) *ConnectionTypesGetCall {
	c := &ConnectionTypesGetCall{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 *ConnectionTypesGetCall) Fields(s ...googleapi.Field) *ConnectionTypesGetCall {
	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 *ConnectionTypesGetCall) IfNoneMatch(entityTag string) *ConnectionTypesGetCall {
	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 *ConnectionTypesGetCall) Context(ctx context.Context) *ConnectionTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConnectionTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConnectionTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{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.connectionTypes.get" call.
// Exactly one of *ConnectionType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *ConnectionType.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 *ConnectionTypesGetCall) Do(opts ...googleapi.CallOption) (*ConnectionType, 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 := &ConnectionType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one connection type by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.connectionTypes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Connection type 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}/connectionTypes/{id}",
	//   "response": {
	//     "$ref": "ConnectionType"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConnectionTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConnectionTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of content categories, possibly filtered. This
// method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of content categories, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ContentCategoriesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ContentCategoriesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.conversions.batchinsert":

type ConversionsBatchinsertCall struct {
	s                             *Service
	profileId                     int64
	conversionsbatchinsertrequest *ConversionsBatchInsertRequest
	urlParams_                    gensupport.URLParams
	ctx_                          context.Context
	header_                       http.Header
}

// Batchinsert: Inserts conversions.
func (r *ConversionsService) Batchinsert(profileId int64, conversionsbatchinsertrequest *ConversionsBatchInsertRequest) *ConversionsBatchinsertCall {
	c := &ConversionsBatchinsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.conversionsbatchinsertrequest = conversionsbatchinsertrequest
	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 *ConversionsBatchinsertCall) Fields(s ...googleapi.Field) *ConversionsBatchinsertCall {
	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 *ConversionsBatchinsertCall) Context(ctx context.Context) *ConversionsBatchinsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ConversionsBatchinsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ConversionsBatchinsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.conversionsbatchinsertrequest)
	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}/conversions/batchinsert")
	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.conversions.batchinsert" call.
// Exactly one of *ConversionsBatchInsertResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *ConversionsBatchInsertResponse.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 *ConversionsBatchinsertCall) Do(opts ...googleapi.CallOption) (*ConversionsBatchInsertResponse, 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 := &ConversionsBatchInsertResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts conversions.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.conversions.batchinsert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/conversions/batchinsert",
	//   "request": {
	//     "$ref": "ConversionsBatchInsertRequest"
	//   },
	//   "response": {
	//     "$ref": "ConversionsBatchInsertResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/ddmconversions"
	//   ]
	// }

}

// method id "dfareporting.countries.get":

type CountriesGetCall struct {
	s            *Service
	profileId    int64
	dartId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CountriesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CountriesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CountriesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CountriesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	mediaInfo_            *gensupport.MediaInfo
	ctx_                  context.Context
	header_               http.Header
}

// 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 {
	c.mediaInfo_ = gensupport.NewInfoFromMedia(r, options)
	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
	c.mediaInfo_ = gensupport.NewInfoFromResumableMedia(r, size, mediaType)
	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.mediaInfo_.SetProgressUpdater(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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeAssetsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeAssetsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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.mediaInfo_ != nil {
		urls = strings.Replace(urls, "https://www.googleapis.com/", "https://www.googleapis.com/upload/", 1)
		c.urlParams_.Set("uploadType", c.mediaInfo_.UploadType())
	}
	if body == nil {
		body = new(bytes.Buffer)
		reqHeaders.Set("Content-Type", "application/json")
	}
	body, getBody, cleanup := c.mediaInfo_.UploadRequest(reqHeaders, body)
	defer cleanup()
	urls += "?" + c.urlParams_.Encode()
	req, _ := http.NewRequest("POST", urls, body)
	req.Header = reqHeaders
	gensupport.SetGetBody(req, getBody)
	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
	}
	rx := c.mediaInfo_.ResumableUpload(res.Header.Get("Location"))
	if rx != nil {
		rx.Client = c.s.client
		rx.UserAgent = c.s.userAgent()
		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 := gensupport.DecodeResponse(target, res); 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.7/userprofiles/{profileId}/creativeAssets/{advertiserId}/creativeAssets"
	//       },
	//       "simple": {
	//         "multipart": true,
	//         "path": "/upload/dfareporting/v2.7/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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_         http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_         http.Header
}

// List: Retrieves a list of creative field values, possibly filtered.
// This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative field values, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "VALUE"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldValuesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldValuesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of creative fields, possibly filtered. This
// method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative fields, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeFieldsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeFieldsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of creative groups, possibly filtered. This
// method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creative groups, possibly filtered. This method supports paging.",
	//   "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",
	//       "maximum": "2",
	//       "minimum": "1",
	//       "type": "integer"
	//     },
	//     "ids": {
	//       "description": "Select only creative groups with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_       http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativeGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativeGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of creatives, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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_DISPLAY"
//   "CUSTOM_DISPLAY_INTERSTITIAL"
//   "DISPLAY"
//   "DISPLAY_IMAGE_GALLERY"
//   "DISPLAY_REDIRECT"
//   "FLASH_INPAGE"
//   "HTML5_BANNER"
//   "IMAGE"
//   "INSTREAM_VIDEO"
//   "INSTREAM_VIDEO_REDIRECT"
//   "INTERNAL_REDIRECT"
//   "INTERSTITIAL_INTERNAL_REDIRECT"
//   "RICH_MEDIA_DISPLAY_BANNER"
//   "RICH_MEDIA_DISPLAY_EXPANDING"
//   "RICH_MEDIA_DISPLAY_INTERSTITIAL"
//   "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL"
//   "RICH_MEDIA_IM_EXPAND"
//   "RICH_MEDIA_INPAGE_FLOATING"
//   "RICH_MEDIA_MOBILE_IN_APP"
//   "RICH_MEDIA_PEEL_DOWN"
//   "TRACKING_TEXT"
//   "VPAID_LINEAR_VIDEO"
//   "VPAID_NON_LINEAR_VIDEO"
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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of creatives, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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_DISPLAY",
	//         "CUSTOM_DISPLAY_INTERSTITIAL",
	//         "DISPLAY",
	//         "DISPLAY_IMAGE_GALLERY",
	//         "DISPLAY_REDIRECT",
	//         "FLASH_INPAGE",
	//         "HTML5_BANNER",
	//         "IMAGE",
	//         "INSTREAM_VIDEO",
	//         "INSTREAM_VIDEO_REDIRECT",
	//         "INTERNAL_REDIRECT",
	//         "INTERSTITIAL_INTERNAL_REDIRECT",
	//         "RICH_MEDIA_DISPLAY_BANNER",
	//         "RICH_MEDIA_DISPLAY_EXPANDING",
	//         "RICH_MEDIA_DISPLAY_INTERSTITIAL",
	//         "RICH_MEDIA_DISPLAY_MULTI_FLOATING_INTERSTITIAL",
	//         "RICH_MEDIA_IM_EXPAND",
	//         "RICH_MEDIA_INPAGE_FLOATING",
	//         "RICH_MEDIA_MOBILE_IN_APP",
	//         "RICH_MEDIA_PEEL_DOWN",
	//         "TRACKING_TEXT",
	//         "VPAID_LINEAR_VIDEO",
	//         "VPAID_NON_LINEAR_VIDEO"
	//       ],
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *CreativesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *CreativesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_               http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DimensionValuesQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DimensionValuesQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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": {
	//       "default": "100",
	//       "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"
	//   ]
	// }

}

// 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 *DimensionValuesQueryCall) Pages(ctx context.Context, f func(*DimensionValueList) 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.directorySiteContacts.get":

type DirectorySiteContactsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySiteContactsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySiteContactsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of directory site contacts, possibly filtered.
// This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySiteContactsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySiteContactsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of directory site contacts, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.insert":

type DirectorySitesInsertCall struct {
	s             *Service
	profileId     int64
	directorysite *DirectorySite
	urlParams_    gensupport.URLParams
	ctx_          context.Context
	header_       http.Header
}

// Insert: Inserts a new directory site.
func (r *DirectorySitesService) Insert(profileId int64, directorysite *DirectorySite) *DirectorySitesInsertCall {
	c := &DirectorySitesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.directorysite = directorysite
	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 *DirectorySitesInsertCall) Fields(s ...googleapi.Field) *DirectorySitesInsertCall {
	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 *DirectorySitesInsertCall) Context(ctx context.Context) *DirectorySitesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.directorysite)
	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}/directorySites")
	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.directorySites.insert" 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 *DirectorySitesInsertCall) 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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new directory site.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.directorySites.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/directorySites",
	//   "request": {
	//     "$ref": "DirectorySite"
	//   },
	//   "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
	header_      http.Header
}

// List: Retrieves a list of directory sites, possibly filtered. This
// method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DirectorySitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DirectorySitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of directory sites, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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.dynamicTargetingKeys.delete":

type DynamicTargetingKeysDeleteCall struct {
	s          *Service
	profileId  int64
	objectId   int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Deletes an existing dynamic targeting key.
func (r *DynamicTargetingKeysService) Delete(profileId int64, objectId int64, name string, objectType string) *DynamicTargetingKeysDeleteCall {
	c := &DynamicTargetingKeysDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.objectId = objectId
	c.urlParams_.Set("name", name)
	c.urlParams_.Set("objectType", objectType)
	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 *DynamicTargetingKeysDeleteCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysDeleteCall {
	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 *DynamicTargetingKeysDeleteCall) Context(ctx context.Context) *DynamicTargetingKeysDeleteCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/dynamicTargetingKeys/{objectId}")
	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),
		"objectId":  strconv.FormatInt(c.objectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.dynamicTargetingKeys.delete" call.
func (c *DynamicTargetingKeysDeleteCall) 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 dynamic targeting key.",
	//   "httpMethod": "DELETE",
	//   "id": "dfareporting.dynamicTargetingKeys.delete",
	//   "parameterOrder": [
	//     "profileId",
	//     "objectId",
	//     "name",
	//     "objectType"
	//   ],
	//   "parameters": {
	//     "name": {
	//       "description": "Name of this dynamic targeting key. This is a required field. Must be less than 256 characters long and cannot contain commas. All characters are converted to lowercase.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "objectId": {
	//       "description": "ID of the object of this dynamic targeting key. This is a required field.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Type of the object of this dynamic targeting key. This is a required field.",
	//       "enum": [
	//         "OBJECT_AD",
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_PLACEMENT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "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}/dynamicTargetingKeys/{objectId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.dynamicTargetingKeys.insert":

type DynamicTargetingKeysInsertCall struct {
	s                   *Service
	profileId           int64
	dynamictargetingkey *DynamicTargetingKey
	urlParams_          gensupport.URLParams
	ctx_                context.Context
	header_             http.Header
}

// Insert: Inserts a new dynamic targeting key. Keys must be created at
// the advertiser level before being assigned to the advertiser's ads,
// creatives, or placements. There is a maximum of 1000 keys per
// advertiser, out of which a maximum of 20 keys can be assigned per ad,
// creative, or placement.
func (r *DynamicTargetingKeysService) Insert(profileId int64, dynamictargetingkey *DynamicTargetingKey) *DynamicTargetingKeysInsertCall {
	c := &DynamicTargetingKeysInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.dynamictargetingkey = dynamictargetingkey
	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 *DynamicTargetingKeysInsertCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysInsertCall {
	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 *DynamicTargetingKeysInsertCall) Context(ctx context.Context) *DynamicTargetingKeysInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.dynamictargetingkey)
	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}/dynamicTargetingKeys")
	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.dynamicTargetingKeys.insert" call.
// Exactly one of *DynamicTargetingKey or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *DynamicTargetingKey.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 *DynamicTargetingKeysInsertCall) Do(opts ...googleapi.CallOption) (*DynamicTargetingKey, 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 := &DynamicTargetingKey{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new dynamic targeting key. Keys must be created at the advertiser level before being assigned to the advertiser's ads, creatives, or placements. There is a maximum of 1000 keys per advertiser, out of which a maximum of 20 keys can be assigned per ad, creative, or placement.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.dynamicTargetingKeys.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "request": {
	//     "$ref": "DynamicTargetingKey"
	//   },
	//   "response": {
	//     "$ref": "DynamicTargetingKey"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.dynamicTargetingKeys.list":

type DynamicTargetingKeysListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of dynamic targeting keys.
func (r *DynamicTargetingKeysService) List(profileId int64) *DynamicTargetingKeysListCall {
	c := &DynamicTargetingKeysListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// dynamic targeting keys whose object has this advertiser ID.
func (c *DynamicTargetingKeysListCall) AdvertiserId(advertiserId int64) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Names sets the optional parameter "names": Select only dynamic
// targeting keys exactly matching these names.
func (c *DynamicTargetingKeysListCall) Names(names ...string) *DynamicTargetingKeysListCall {
	c.urlParams_.SetMulti("names", append([]string{}, names...))
	return c
}

// ObjectId sets the optional parameter "objectId": Select only dynamic
// targeting keys with this object ID.
func (c *DynamicTargetingKeysListCall) ObjectId(objectId int64) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("objectId", fmt.Sprint(objectId))
	return c
}

// ObjectType sets the optional parameter "objectType": Select only
// dynamic targeting keys with this object type.
//
// Possible values:
//   "OBJECT_AD"
//   "OBJECT_ADVERTISER"
//   "OBJECT_CREATIVE"
//   "OBJECT_PLACEMENT"
func (c *DynamicTargetingKeysListCall) ObjectType(objectType string) *DynamicTargetingKeysListCall {
	c.urlParams_.Set("objectType", objectType)
	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 *DynamicTargetingKeysListCall) Fields(s ...googleapi.Field) *DynamicTargetingKeysListCall {
	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 *DynamicTargetingKeysListCall) IfNoneMatch(entityTag string) *DynamicTargetingKeysListCall {
	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 *DynamicTargetingKeysListCall) Context(ctx context.Context) *DynamicTargetingKeysListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *DynamicTargetingKeysListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *DynamicTargetingKeysListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/dynamicTargetingKeys")
	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.dynamicTargetingKeys.list" call.
// Exactly one of *DynamicTargetingKeysListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *DynamicTargetingKeysListResponse.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 *DynamicTargetingKeysListCall) Do(opts ...googleapi.CallOption) (*DynamicTargetingKeysListResponse, 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 := &DynamicTargetingKeysListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of dynamic targeting keys.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.dynamicTargetingKeys.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only dynamic targeting keys whose object has this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "names": {
	//       "description": "Select only dynamic targeting keys exactly matching these names.",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "objectId": {
	//       "description": "Select only dynamic targeting keys with this object ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "objectType": {
	//       "description": "Select only dynamic targeting keys with this object type.",
	//       "enum": [
	//         "OBJECT_AD",
	//         "OBJECT_ADVERTISER",
	//         "OBJECT_CREATIVE",
	//         "OBJECT_PLACEMENT"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         "",
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/dynamicTargetingKeys",
	//   "response": {
	//     "$ref": "DynamicTargetingKeysListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.eventTags.delete":

type EventTagsDeleteCall struct {
	s          *Service
	profileId  int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *EventTagsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *EventTagsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// Get: Retrieves a report file by its report ID and file ID. This
// method supports media download.
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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file by its report ID and file ID. This method supports media download.",
	//   "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
	header_      http.Header
}

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

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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": {
	//       "default": "10",
	//       "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.",
	//       "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.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesGeneratetagCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesGeneratetagCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of floodlight activities, possibly filtered.
// This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activities, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_            http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivitiesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivitiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type FloodlightActivityGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_                 http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of floodlight activity groups, possibly
// filtered. This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of floodlight activity groups, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_                 http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_                 http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightActivityGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightActivityGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_                 http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_                 http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *FloodlightConfigurationsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *FloodlightConfigurationsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.inventoryItems.get":

type InventoryItemsGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one inventory item by ID.
func (r *InventoryItemsService) Get(profileId int64, projectId int64, id int64) *InventoryItemsGetCall {
	c := &InventoryItemsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	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 *InventoryItemsGetCall) Fields(s ...googleapi.Field) *InventoryItemsGetCall {
	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 *InventoryItemsGetCall) IfNoneMatch(entityTag string) *InventoryItemsGetCall {
	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 *InventoryItemsGetCall) Context(ctx context.Context) *InventoryItemsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InventoryItemsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventoryItemsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/inventoryItems/{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),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.inventoryItems.get" call.
// Exactly one of *InventoryItem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *InventoryItem.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 *InventoryItemsGetCall) Do(opts ...googleapi.CallOption) (*InventoryItem, 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 := &InventoryItem{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one inventory item by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.inventoryItems.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Inventory item 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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/inventoryItems/{id}",
	//   "response": {
	//     "$ref": "InventoryItem"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.inventoryItems.list":

type InventoryItemsListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of inventory items, possibly filtered. This
// method supports paging.
func (r *InventoryItemsService) List(profileId int64, projectId int64) *InventoryItemsListCall {
	c := &InventoryItemsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Ids sets the optional parameter "ids": Select only inventory items
// with these IDs.
func (c *InventoryItemsListCall) Ids(ids ...int64) *InventoryItemsListCall {
	var ids_ []string
	for _, v := range ids {
		ids_ = append(ids_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("ids", ids_)
	return c
}

// InPlan sets the optional parameter "inPlan": Select only inventory
// items that are in plan.
func (c *InventoryItemsListCall) InPlan(inPlan bool) *InventoryItemsListCall {
	c.urlParams_.Set("inPlan", fmt.Sprint(inPlan))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *InventoryItemsListCall) MaxResults(maxResults int64) *InventoryItemsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderId sets the optional parameter "orderId": Select only inventory
// items that belong to specified orders.
func (c *InventoryItemsListCall) OrderId(orderId ...int64) *InventoryItemsListCall {
	var orderId_ []string
	for _, v := range orderId {
		orderId_ = append(orderId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("orderId", orderId_)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *InventoryItemsListCall) PageToken(pageToken string) *InventoryItemsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SiteId sets the optional parameter "siteId": Select only inventory
// items that are associated with these sites.
func (c *InventoryItemsListCall) SiteId(siteId ...int64) *InventoryItemsListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *InventoryItemsListCall) SortField(sortField string) *InventoryItemsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *InventoryItemsListCall) SortOrder(sortOrder string) *InventoryItemsListCall {
	c.urlParams_.Set("sortOrder", sortOrder)
	return c
}

// Type sets the optional parameter "type": Select only inventory items
// with this type.
//
// Possible values:
//   "PLANNING_PLACEMENT_TYPE_CREDIT"
//   "PLANNING_PLACEMENT_TYPE_REGULAR"
func (c *InventoryItemsListCall) Type(type_ string) *InventoryItemsListCall {
	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 *InventoryItemsListCall) Fields(s ...googleapi.Field) *InventoryItemsListCall {
	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 *InventoryItemsListCall) IfNoneMatch(entityTag string) *InventoryItemsListCall {
	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 *InventoryItemsListCall) Context(ctx context.Context) *InventoryItemsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *InventoryItemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *InventoryItemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/inventoryItems")
	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),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.inventoryItems.list" call.
// Exactly one of *InventoryItemsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *InventoryItemsListResponse.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 *InventoryItemsListCall) Do(opts ...googleapi.CallOption) (*InventoryItemsListResponse, 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 := &InventoryItemsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of inventory items, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.inventoryItems.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only inventory items with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "inPlan": {
	//       "description": "Select only inventory items that are in plan.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderId": {
	//       "description": "Select only inventory items that belong to specified orders.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only inventory items that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "type": {
	//       "description": "Select only inventory items with this type.",
	//       "enum": [
	//         "PLANNING_PLACEMENT_TYPE_CREDIT",
	//         "PLANNING_PLACEMENT_TYPE_REGULAR"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/inventoryItems",
	//   "response": {
	//     "$ref": "InventoryItemsListResponse"
	//   },
	//   "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 *InventoryItemsListCall) Pages(ctx context.Context, f func(*InventoryItemsListResponse) 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.landingPages.delete":

type LandingPagesDeleteCall struct {
	s          *Service
	profileId  int64
	campaignId int64
	id         int64
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_     http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_     http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_     http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LandingPagesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LandingPagesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.languages.list":

type LanguagesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of languages.
func (r *LanguagesService) List(profileId int64) *LanguagesListCall {
	c := &LanguagesListCall{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 *LanguagesListCall) Fields(s ...googleapi.Field) *LanguagesListCall {
	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 *LanguagesListCall) IfNoneMatch(entityTag string) *LanguagesListCall {
	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 *LanguagesListCall) Context(ctx context.Context) *LanguagesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *LanguagesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LanguagesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/languages")
	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.languages.list" call.
// Exactly one of *LanguagesListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LanguagesListResponse.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 *LanguagesListCall) Do(opts ...googleapi.CallOption) (*LanguagesListResponse, 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 := &LanguagesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of languages.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.languages.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/languages",
	//   "response": {
	//     "$ref": "LanguagesListResponse"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MetrosListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MetrosListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type MobileCarriersGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one mobile carrier by ID.
func (r *MobileCarriersService) Get(profileId int64, id int64) *MobileCarriersGetCall {
	c := &MobileCarriersGetCall{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 *MobileCarriersGetCall) Fields(s ...googleapi.Field) *MobileCarriersGetCall {
	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 *MobileCarriersGetCall) IfNoneMatch(entityTag string) *MobileCarriersGetCall {
	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 *MobileCarriersGetCall) Context(ctx context.Context) *MobileCarriersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileCarriersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileCarriersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{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.mobileCarriers.get" call.
// Exactly one of *MobileCarrier or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *MobileCarrier.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 *MobileCarriersGetCall) Do(opts ...googleapi.CallOption) (*MobileCarrier, 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 := &MobileCarrier{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one mobile carrier by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.mobileCarriers.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Mobile carrier 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}/mobileCarriers/{id}",
	//   "response": {
	//     "$ref": "MobileCarrier"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *MobileCarriersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *MobileCarriersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type OperatingSystemVersionsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one operating system version by ID.
func (r *OperatingSystemVersionsService) Get(profileId int64, id int64) *OperatingSystemVersionsGetCall {
	c := &OperatingSystemVersionsGetCall{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 *OperatingSystemVersionsGetCall) Fields(s ...googleapi.Field) *OperatingSystemVersionsGetCall {
	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 *OperatingSystemVersionsGetCall) IfNoneMatch(entityTag string) *OperatingSystemVersionsGetCall {
	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 *OperatingSystemVersionsGetCall) Context(ctx context.Context) *OperatingSystemVersionsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemVersionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemVersionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{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.operatingSystemVersions.get" call.
// Exactly one of *OperatingSystemVersion or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OperatingSystemVersion.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 *OperatingSystemVersionsGetCall) Do(opts ...googleapi.CallOption) (*OperatingSystemVersion, 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 := &OperatingSystemVersion{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one operating system version by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystemVersions.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Operating system version 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}/operatingSystemVersions/{id}",
	//   "response": {
	//     "$ref": "OperatingSystemVersion"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemVersionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemVersionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type OperatingSystemsGetCall struct {
	s            *Service
	profileId    int64
	dartId       int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one operating system by DART ID.
func (r *OperatingSystemsService) Get(profileId int64, dartId int64) *OperatingSystemsGetCall {
	c := &OperatingSystemsGetCall{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 *OperatingSystemsGetCall) Fields(s ...googleapi.Field) *OperatingSystemsGetCall {
	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 *OperatingSystemsGetCall) IfNoneMatch(entityTag string) *OperatingSystemsGetCall {
	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 *OperatingSystemsGetCall) Context(ctx context.Context) *OperatingSystemsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{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.operatingSystems.get" call.
// Exactly one of *OperatingSystem or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OperatingSystem.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 *OperatingSystemsGetCall) Do(opts ...googleapi.CallOption) (*OperatingSystem, 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 := &OperatingSystem{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one operating system by DART ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.operatingSystems.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "dartId"
	//   ],
	//   "parameters": {
	//     "dartId": {
	//       "description": "Operating system 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}/operatingSystems/{dartId}",
	//   "response": {
	//     "$ref": "OperatingSystem"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OperatingSystemsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OperatingSystemsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.orderDocuments.get":

type OrderDocumentsGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one order document by ID.
func (r *OrderDocumentsService) Get(profileId int64, projectId int64, id int64) *OrderDocumentsGetCall {
	c := &OrderDocumentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	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 *OrderDocumentsGetCall) Fields(s ...googleapi.Field) *OrderDocumentsGetCall {
	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 *OrderDocumentsGetCall) IfNoneMatch(entityTag string) *OrderDocumentsGetCall {
	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 *OrderDocumentsGetCall) Context(ctx context.Context) *OrderDocumentsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrderDocumentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrderDocumentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/orderDocuments/{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),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orderDocuments.get" call.
// Exactly one of *OrderDocument or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *OrderDocument.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 *OrderDocumentsGetCall) Do(opts ...googleapi.CallOption) (*OrderDocument, 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 := &OrderDocument{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one order document by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orderDocuments.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Order document 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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orderDocuments/{id}",
	//   "response": {
	//     "$ref": "OrderDocument"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.orderDocuments.list":

type OrderDocumentsListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of order documents, possibly filtered. This
// method supports paging.
func (r *OrderDocumentsService) List(profileId int64, projectId int64) *OrderDocumentsListCall {
	c := &OrderDocumentsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Approved sets the optional parameter "approved": Select only order
// documents that have been approved by at least one user.
func (c *OrderDocumentsListCall) Approved(approved bool) *OrderDocumentsListCall {
	c.urlParams_.Set("approved", fmt.Sprint(approved))
	return c
}

// Ids sets the optional parameter "ids": Select only order documents
// with these IDs.
func (c *OrderDocumentsListCall) Ids(ids ...int64) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) MaxResults(maxResults int64) *OrderDocumentsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// OrderId sets the optional parameter "orderId": Select only order
// documents for specified orders.
func (c *OrderDocumentsListCall) OrderId(orderId ...int64) *OrderDocumentsListCall {
	var orderId_ []string
	for _, v := range orderId {
		orderId_ = append(orderId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("orderId", orderId_)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *OrderDocumentsListCall) PageToken(pageToken string) *OrderDocumentsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for order documents by name or ID. Wildcards (*) are
// allowed. For example, "orderdocument*2015" will return order
// documents with names like "orderdocument June 2015", "orderdocument
// April 2015", or simply "orderdocument 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 "orderdocument" will match
// order documents with name "my orderdocument", "orderdocument 2015",
// or simply "orderdocument".
func (c *OrderDocumentsListCall) SearchString(searchString string) *OrderDocumentsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteId sets the optional parameter "siteId": Select only order
// documents that are associated with these sites.
func (c *OrderDocumentsListCall) SiteId(siteId ...int64) *OrderDocumentsListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *OrderDocumentsListCall) SortField(sortField string) *OrderDocumentsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *OrderDocumentsListCall) SortOrder(sortOrder string) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) Fields(s ...googleapi.Field) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) IfNoneMatch(entityTag string) *OrderDocumentsListCall {
	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 *OrderDocumentsListCall) Context(ctx context.Context) *OrderDocumentsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrderDocumentsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrderDocumentsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/orderDocuments")
	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),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orderDocuments.list" call.
// Exactly one of *OrderDocumentsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *OrderDocumentsListResponse.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 *OrderDocumentsListCall) Do(opts ...googleapi.CallOption) (*OrderDocumentsListResponse, 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 := &OrderDocumentsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of order documents, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orderDocuments.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "approved": {
	//       "description": "Select only order documents that have been approved by at least one user.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "ids": {
	//       "description": "Select only order documents with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "orderId": {
	//       "description": "Select only order documents for specified orders.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for order documents.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for order documents by name or ID. Wildcards (*) are allowed. For example, \"orderdocument*2015\" will return order documents with names like \"orderdocument June 2015\", \"orderdocument April 2015\", or simply \"orderdocument 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 \"orderdocument\" will match order documents with name \"my orderdocument\", \"orderdocument 2015\", or simply \"orderdocument\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only order documents that are associated with these sites.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orderDocuments",
	//   "response": {
	//     "$ref": "OrderDocumentsListResponse"
	//   },
	//   "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 *OrderDocumentsListCall) Pages(ctx context.Context, f func(*OrderDocumentsListResponse) 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.orders.get":

type OrdersGetCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one order by ID.
func (r *OrdersService) Get(profileId int64, projectId int64, id int64) *OrdersGetCall {
	c := &OrdersGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	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 *OrdersGetCall) Fields(s ...googleapi.Field) *OrdersGetCall {
	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 *OrdersGetCall) IfNoneMatch(entityTag string) *OrdersGetCall {
	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 *OrdersGetCall) Context(ctx context.Context) *OrdersGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrdersGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrdersGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/orders/{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),
		"projectId": strconv.FormatInt(c.projectId, 10),
		"id":        strconv.FormatInt(c.id, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orders.get" call.
// Exactly one of *Order or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Order.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 *OrdersGetCall) Do(opts ...googleapi.CallOption) (*Order, 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 := &Order{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one order by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orders.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Order 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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for orders.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orders/{id}",
	//   "response": {
	//     "$ref": "Order"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.orders.list":

type OrdersListCall struct {
	s            *Service
	profileId    int64
	projectId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of orders, possibly filtered. This method
// supports paging.
func (r *OrdersService) List(profileId int64, projectId int64) *OrdersListCall {
	c := &OrdersListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.projectId = projectId
	return c
}

// Ids sets the optional parameter "ids": Select only orders with these
// IDs.
func (c *OrdersListCall) Ids(ids ...int64) *OrdersListCall {
	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 *OrdersListCall) MaxResults(maxResults int64) *OrdersListCall {
	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 *OrdersListCall) PageToken(pageToken string) *OrdersListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for orders by name or ID. Wildcards (*) are allowed. For
// example, "order*2015" will return orders with names like "order June
// 2015", "order April 2015", or simply "order 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 "order" will match
// orders with name "my order", "order 2015", or simply "order".
func (c *OrdersListCall) SearchString(searchString string) *OrdersListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SiteId sets the optional parameter "siteId": Select only orders that
// are associated with these site IDs.
func (c *OrdersListCall) SiteId(siteId ...int64) *OrdersListCall {
	var siteId_ []string
	for _, v := range siteId {
		siteId_ = append(siteId_, fmt.Sprint(v))
	}
	c.urlParams_.SetMulti("siteId", siteId_)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *OrdersListCall) SortField(sortField string) *OrdersListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *OrdersListCall) SortOrder(sortOrder string) *OrdersListCall {
	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 *OrdersListCall) Fields(s ...googleapi.Field) *OrdersListCall {
	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 *OrdersListCall) IfNoneMatch(entityTag string) *OrdersListCall {
	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 *OrdersListCall) Context(ctx context.Context) *OrdersListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *OrdersListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *OrdersListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{projectId}/orders")
	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),
		"projectId": strconv.FormatInt(c.projectId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.orders.list" call.
// Exactly one of *OrdersListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *OrdersListResponse.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 *OrdersListCall) Do(opts ...googleapi.CallOption) (*OrdersListResponse, 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 := &OrdersListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of orders, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.orders.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "projectId"
	//   ],
	//   "parameters": {
	//     "ids": {
	//       "description": "Select only orders with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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"
	//     },
	//     "projectId": {
	//       "description": "Project ID for orders.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "searchString": {
	//       "description": "Allows searching for orders by name or ID. Wildcards (*) are allowed. For example, \"order*2015\" will return orders with names like \"order June 2015\", \"order April 2015\", or simply \"order 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 \"order\" will match orders with name \"my order\", \"order 2015\", or simply \"order\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "siteId": {
	//       "description": "Select only orders that are associated with these site IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects/{projectId}/orders",
	//   "response": {
	//     "$ref": "OrdersListResponse"
	//   },
	//   "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 *OrdersListCall) Pages(ctx context.Context, f func(*OrdersListResponse) 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.get":

type PlacementGroupsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_        http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of placement groups, possibly filtered. This
// method supports paging.
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
}

// MaxEndDate sets the optional parameter "maxEndDate": Select only
// placements or placement groups whose end date is on or before the
// specified maxEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MaxEndDate(maxEndDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("maxEndDate", maxEndDate)
	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
}

// MaxStartDate sets the optional parameter "maxStartDate": Select only
// placements or placement groups whose start date is on or before the
// specified maxStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MaxStartDate(maxStartDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("maxStartDate", maxStartDate)
	return c
}

// MinEndDate sets the optional parameter "minEndDate": Select only
// placements or placement groups whose end date is on or after the
// specified minEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MinEndDate(minEndDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("minEndDate", minEndDate)
	return c
}

// MinStartDate sets the optional parameter "minStartDate": Select only
// placements or placement groups whose start date is on or after the
// specified minStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementGroupsListCall) MinStartDate(minStartDate string) *PlacementGroupsListCall {
	c.urlParams_.Set("minStartDate", minStartDate)
	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_CPM_ACTIVEVIEW"
//   "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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement groups, possibly filtered. This method supports paging.",
	//   "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"
	//     },
	//     "maxEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or before the specified maxEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "800",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "800",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "maxStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or before the specified maxStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or after the specified minEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or after the specified minStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "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_CPM_ACTIVEVIEW",
	//         "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_        http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_        http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementGroupsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementGroupsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_           http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of placement strategies, possibly filtered.
// This method supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placement strategies, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_           http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_           http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementStrategiesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementStrategiesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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.
//
// Note: PLACEMENT_TAG_STANDARD can only be generated for 1x1
// 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_INSTREAM_VIDEO_PREFETCH_VAST_4"
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsGeneratetagsCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsGeneratetagsCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.\n\nNote: PLACEMENT_TAG_STANDARD can only be generated for 1x1 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_INSTREAM_VIDEO_PREFETCH_VAST_4",
	//         "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of placements, possibly filtered. This method
// supports paging.
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.
// DISPLAY and DISPLAY_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"
//   "DISPLAY"
//   "DISPLAY_INTERSTITIAL"
//   "IN_STREAM_VIDEO"
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
}

// MaxEndDate sets the optional parameter "maxEndDate": Select only
// placements or placement groups whose end date is on or before the
// specified maxEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MaxEndDate(maxEndDate string) *PlacementsListCall {
	c.urlParams_.Set("maxEndDate", maxEndDate)
	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
}

// MaxStartDate sets the optional parameter "maxStartDate": Select only
// placements or placement groups whose start date is on or before the
// specified maxStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MaxStartDate(maxStartDate string) *PlacementsListCall {
	c.urlParams_.Set("maxStartDate", maxStartDate)
	return c
}

// MinEndDate sets the optional parameter "minEndDate": Select only
// placements or placement groups whose end date is on or after the
// specified minEndDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MinEndDate(minEndDate string) *PlacementsListCall {
	c.urlParams_.Set("minEndDate", minEndDate)
	return c
}

// MinStartDate sets the optional parameter "minStartDate": Select only
// placements or placement groups whose start date is on or after the
// specified minStartDate. The date should be formatted as "yyyy-MM-dd".
func (c *PlacementsListCall) MinStartDate(minStartDate string) *PlacementsListCall {
	c.urlParams_.Set("minStartDate", minStartDate)
	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_CPM_ACTIVEVIEW"
//   "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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of placements, possibly filtered. This method supports paging.",
	//   "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. DISPLAY and DISPLAY_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",
	//         "DISPLAY",
	//         "DISPLAY_INTERSTITIAL",
	//         "IN_STREAM_VIDEO"
	//       ],
	//       "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"
	//     },
	//     "maxEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or before the specified maxEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "maxStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or before the specified maxStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minEndDate": {
	//       "description": "Select only placements or placement groups whose end date is on or after the specified minEndDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "minStartDate": {
	//       "description": "Select only placements or placement groups whose start date is on or after the specified minStartDate. The date should be formatted as \"yyyy-MM-dd\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "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_CPM_ACTIVEVIEW",
	//         "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlacementsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlacementsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type PlatformTypesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one platform type by ID.
func (r *PlatformTypesService) Get(profileId int64, id int64) *PlatformTypesGetCall {
	c := &PlatformTypesGetCall{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 *PlatformTypesGetCall) Fields(s ...googleapi.Field) *PlatformTypesGetCall {
	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 *PlatformTypesGetCall) IfNoneMatch(entityTag string) *PlatformTypesGetCall {
	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 *PlatformTypesGetCall) Context(ctx context.Context) *PlatformTypesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlatformTypesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlatformTypesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{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.platformTypes.get" call.
// Exactly one of *PlatformType or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PlatformType.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 *PlatformTypesGetCall) Do(opts ...googleapi.CallOption) (*PlatformType, 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 := &PlatformType{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one platform type by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.platformTypes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Platform type 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}/platformTypes/{id}",
	//   "response": {
	//     "$ref": "PlatformType"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PlatformTypesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PlatformTypesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.get":

type PostalCodesGetCall struct {
	s            *Service
	profileId    int64
	code         string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one postal code by ID.
func (r *PostalCodesService) Get(profileId int64, code string) *PostalCodesGetCall {
	c := &PostalCodesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.code = code
	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 *PostalCodesGetCall) Fields(s ...googleapi.Field) *PostalCodesGetCall {
	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 *PostalCodesGetCall) IfNoneMatch(entityTag string) *PostalCodesGetCall {
	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 *PostalCodesGetCall) Context(ctx context.Context) *PostalCodesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PostalCodesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PostalCodesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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/{code}")
	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),
		"code":      c.code,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.postalCodes.get" call.
// Exactly one of *PostalCode or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *PostalCode.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 *PostalCodesGetCall) Do(opts ...googleapi.CallOption) (*PostalCode, 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 := &PostalCode{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one postal code by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.postalCodes.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "code"
	//   ],
	//   "parameters": {
	//     "code": {
	//       "description": "Postal code ID.",
	//       "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}/postalCodes/{code}",
	//   "response": {
	//     "$ref": "PostalCode"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *PostalCodesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *PostalCodesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.projects.get":

type ProjectsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one project by ID.
func (r *ProjectsService) Get(profileId int64, id int64) *ProjectsGetCall {
	c := &ProjectsGetCall{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 *ProjectsGetCall) Fields(s ...googleapi.Field) *ProjectsGetCall {
	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 *ProjectsGetCall) IfNoneMatch(entityTag string) *ProjectsGetCall {
	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 *ProjectsGetCall) Context(ctx context.Context) *ProjectsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects/{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.projects.get" call.
// Exactly one of *Project or error will be non-nil. Any non-2xx status
// code is an error. Response headers are in either
// *Project.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 *ProjectsGetCall) Do(opts ...googleapi.CallOption) (*Project, 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 := &Project{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one project by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.projects.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Project 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}/projects/{id}",
	//   "response": {
	//     "$ref": "Project"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.projects.list":

type ProjectsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of projects, possibly filtered. This method
// supports paging.
func (r *ProjectsService) List(profileId int64) *ProjectsListCall {
	c := &ProjectsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserIds sets the optional parameter "advertiserIds": Select
// only projects with these advertiser IDs.
func (c *ProjectsListCall) AdvertiserIds(advertiserIds ...int64) *ProjectsListCall {
	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 projects with
// these IDs.
func (c *ProjectsListCall) Ids(ids ...int64) *ProjectsListCall {
	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 *ProjectsListCall) MaxResults(maxResults int64) *ProjectsListCall {
	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 *ProjectsListCall) PageToken(pageToken string) *ProjectsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SearchString sets the optional parameter "searchString": Allows
// searching for projects by name or ID. Wildcards (*) are allowed. For
// example, "project*2015" will return projects with names like "project
// June 2015", "project April 2015", or simply "project 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 "project" will
// match projects with name "my project", "project 2015", or simply
// "project".
func (c *ProjectsListCall) SearchString(searchString string) *ProjectsListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *ProjectsListCall) SortField(sortField string) *ProjectsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *ProjectsListCall) SortOrder(sortOrder string) *ProjectsListCall {
	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 *ProjectsListCall) Fields(s ...googleapi.Field) *ProjectsListCall {
	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 *ProjectsListCall) IfNoneMatch(entityTag string) *ProjectsListCall {
	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 *ProjectsListCall) Context(ctx context.Context) *ProjectsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ProjectsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ProjectsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/projects")
	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.projects.list" call.
// Exactly one of *ProjectsListResponse or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *ProjectsListResponse.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 *ProjectsListCall) Do(opts ...googleapi.CallOption) (*ProjectsListResponse, 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 := &ProjectsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of projects, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.projects.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserIds": {
	//       "description": "Select only projects with these advertiser IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only projects with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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 projects by name or ID. Wildcards (*) are allowed. For example, \"project*2015\" will return projects with names like \"project June 2015\", \"project April 2015\", or simply \"project 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 \"project\" will match projects with name \"my project\", \"project 2015\", or simply \"project\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/projects",
	//   "response": {
	//     "$ref": "ProjectsListResponse"
	//   },
	//   "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 *ProjectsListCall) Pages(ctx context.Context, f func(*ProjectsListResponse) 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.regions.list":

type RegionsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RegionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RegionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.remarketingListShares.get":

type RemarketingListSharesGetCall struct {
	s                 *Service
	profileId         int64
	remarketingListId int64
	urlParams_        gensupport.URLParams
	ifNoneMatch_      string
	ctx_              context.Context
	header_           http.Header
}

// Get: Gets one remarketing list share by remarketing list ID.
func (r *RemarketingListSharesService) Get(profileId int64, remarketingListId int64) *RemarketingListSharesGetCall {
	c := &RemarketingListSharesGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketingListId = remarketingListId
	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 *RemarketingListSharesGetCall) Fields(s ...googleapi.Field) *RemarketingListSharesGetCall {
	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 *RemarketingListSharesGetCall) IfNoneMatch(entityTag string) *RemarketingListSharesGetCall {
	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 *RemarketingListSharesGetCall) Context(ctx context.Context) *RemarketingListSharesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/remarketingListShares/{remarketingListId}")
	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),
		"remarketingListId": strconv.FormatInt(c.remarketingListId, 10),
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "dfareporting.remarketingListShares.get" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.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 *RemarketingListSharesGetCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, 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 := &RemarketingListShare{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one remarketing list share by remarketing list ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingListShares.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "remarketingListId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListId": {
	//       "description": "Remarketing list ID.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingListShares/{remarketingListId}",
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingListShares.patch":

type RemarketingListSharesPatchCall struct {
	s                    *Service
	profileId            int64
	remarketinglistshare *RemarketingListShare
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Patch: Updates an existing remarketing list share. This method
// supports patch semantics.
func (r *RemarketingListSharesService) Patch(profileId int64, remarketingListId int64, remarketinglistshare *RemarketingListShare) *RemarketingListSharesPatchCall {
	c := &RemarketingListSharesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("remarketingListId", fmt.Sprint(remarketingListId))
	c.remarketinglistshare = remarketinglistshare
	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 *RemarketingListSharesPatchCall) Fields(s ...googleapi.Field) *RemarketingListSharesPatchCall {
	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 *RemarketingListSharesPatchCall) Context(ctx context.Context) *RemarketingListSharesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.remarketinglistshare)
	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}/remarketingListShares")
	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.remarketingListShares.patch" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.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 *RemarketingListSharesPatchCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, 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 := &RemarketingListShare{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing remarketing list share. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.remarketingListShares.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "remarketingListId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "remarketingListId": {
	//       "description": "Remarketing list ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingListShares",
	//   "request": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingListShares.update":

type RemarketingListSharesUpdateCall struct {
	s                    *Service
	profileId            int64
	remarketinglistshare *RemarketingListShare
	urlParams_           gensupport.URLParams
	ctx_                 context.Context
	header_              http.Header
}

// Update: Updates an existing remarketing list share.
func (r *RemarketingListSharesService) Update(profileId int64, remarketinglistshare *RemarketingListShare) *RemarketingListSharesUpdateCall {
	c := &RemarketingListSharesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglistshare = remarketinglistshare
	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 *RemarketingListSharesUpdateCall) Fields(s ...googleapi.Field) *RemarketingListSharesUpdateCall {
	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 *RemarketingListSharesUpdateCall) Context(ctx context.Context) *RemarketingListSharesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListSharesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListSharesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.remarketinglistshare)
	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}/remarketingListShares")
	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.remarketingListShares.update" call.
// Exactly one of *RemarketingListShare or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *RemarketingListShare.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 *RemarketingListSharesUpdateCall) Do(opts ...googleapi.CallOption) (*RemarketingListShare, 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 := &RemarketingListShare{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing remarketing list share.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.remarketingListShares.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingListShares",
	//   "request": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "response": {
	//     "$ref": "RemarketingListShare"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.get":

type RemarketingListsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one remarketing list by ID.
func (r *RemarketingListsService) Get(profileId int64, id int64) *RemarketingListsGetCall {
	c := &RemarketingListsGetCall{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 *RemarketingListsGetCall) Fields(s ...googleapi.Field) *RemarketingListsGetCall {
	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 *RemarketingListsGetCall) IfNoneMatch(entityTag string) *RemarketingListsGetCall {
	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 *RemarketingListsGetCall) Context(ctx context.Context) *RemarketingListsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/remarketingLists/{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.remarketingLists.get" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.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 *RemarketingListsGetCall) Do(opts ...googleapi.CallOption) (*RemarketingList, 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 := &RemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one remarketing list by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingLists.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Remarketing list 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}/remarketingLists/{id}",
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.insert":

type RemarketingListsInsertCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Insert: Inserts a new remarketing list.
func (r *RemarketingListsService) Insert(profileId int64, remarketinglist *RemarketingList) *RemarketingListsInsertCall {
	c := &RemarketingListsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglist = remarketinglist
	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 *RemarketingListsInsertCall) Fields(s ...googleapi.Field) *RemarketingListsInsertCall {
	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 *RemarketingListsInsertCall) Context(ctx context.Context) *RemarketingListsInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.remarketinglist)
	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}/remarketingLists")
	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.remarketingLists.insert" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.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 *RemarketingListsInsertCall) Do(opts ...googleapi.CallOption) (*RemarketingList, 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 := &RemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new remarketing list.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.remarketingLists.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.list":

type RemarketingListsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of remarketing lists, possibly filtered. This
// method supports paging.
func (r *RemarketingListsService) List(profileId int64, advertiserId int64) *RemarketingListsListCall {
	c := &RemarketingListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Active sets the optional parameter "active": Select only active or
// only inactive remarketing lists.
func (c *RemarketingListsListCall) Active(active bool) *RemarketingListsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// FloodlightActivityId sets the optional parameter
// "floodlightActivityId": Select only remarketing lists that have this
// floodlight activity ID.
func (c *RemarketingListsListCall) FloodlightActivityId(floodlightActivityId int64) *RemarketingListsListCall {
	c.urlParams_.Set("floodlightActivityId", fmt.Sprint(floodlightActivityId))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *RemarketingListsListCall) MaxResults(maxResults int64) *RemarketingListsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Name sets the optional parameter "name": Allows searching for objects
// by name or ID. Wildcards (*) are allowed. For example, "remarketing
// list*2015" will return objects with names like "remarketing list June
// 2015", "remarketing list April 2015", or simply "remarketing list
// 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 "remarketing list" will match objects with name "my remarketing
// list", "remarketing list 2015", or simply "remarketing list".
func (c *RemarketingListsListCall) Name(name string) *RemarketingListsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *RemarketingListsListCall) PageToken(pageToken string) *RemarketingListsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *RemarketingListsListCall) SortField(sortField string) *RemarketingListsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *RemarketingListsListCall) SortOrder(sortOrder string) *RemarketingListsListCall {
	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 *RemarketingListsListCall) Fields(s ...googleapi.Field) *RemarketingListsListCall {
	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 *RemarketingListsListCall) IfNoneMatch(entityTag string) *RemarketingListsListCall {
	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 *RemarketingListsListCall) Context(ctx context.Context) *RemarketingListsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/remarketingLists")
	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.remarketingLists.list" call.
// Exactly one of *RemarketingListsListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *RemarketingListsListResponse.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 *RemarketingListsListCall) Do(opts ...googleapi.CallOption) (*RemarketingListsListResponse, 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 := &RemarketingListsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of remarketing lists, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.remarketingLists.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active or only inactive remarketing lists.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only remarketing lists owned by this advertiser.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "floodlightActivityId": {
	//       "description": "Select only remarketing lists that have this floodlight activity ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"remarketing list*2015\" will return objects with names like \"remarketing list June 2015\", \"remarketing list April 2015\", or simply \"remarketing list 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 \"remarketing list\" will match objects with name \"my remarketing list\", \"remarketing list 2015\", or simply \"remarketing list\".",
	//       "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"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "response": {
	//     "$ref": "RemarketingListsListResponse"
	//   },
	//   "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 *RemarketingListsListCall) Pages(ctx context.Context, f func(*RemarketingListsListResponse) 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.remarketingLists.patch":

type RemarketingListsPatchCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Patch: Updates an existing remarketing list. This method supports
// patch semantics.
func (r *RemarketingListsService) Patch(profileId int64, id int64, remarketinglist *RemarketingList) *RemarketingListsPatchCall {
	c := &RemarketingListsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.remarketinglist = remarketinglist
	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 *RemarketingListsPatchCall) Fields(s ...googleapi.Field) *RemarketingListsPatchCall {
	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 *RemarketingListsPatchCall) Context(ctx context.Context) *RemarketingListsPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.remarketinglist)
	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}/remarketingLists")
	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.remarketingLists.patch" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.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 *RemarketingListsPatchCall) Do(opts ...googleapi.CallOption) (*RemarketingList, 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 := &RemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing remarketing list. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.remarketingLists.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Remarketing list 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}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.remarketingLists.update":

type RemarketingListsUpdateCall struct {
	s               *Service
	profileId       int64
	remarketinglist *RemarketingList
	urlParams_      gensupport.URLParams
	ctx_            context.Context
	header_         http.Header
}

// Update: Updates an existing remarketing list.
func (r *RemarketingListsService) Update(profileId int64, remarketinglist *RemarketingList) *RemarketingListsUpdateCall {
	c := &RemarketingListsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.remarketinglist = remarketinglist
	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 *RemarketingListsUpdateCall) Fields(s ...googleapi.Field) *RemarketingListsUpdateCall {
	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 *RemarketingListsUpdateCall) Context(ctx context.Context) *RemarketingListsUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *RemarketingListsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *RemarketingListsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.remarketinglist)
	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}/remarketingLists")
	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.remarketingLists.update" call.
// Exactly one of *RemarketingList or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *RemarketingList.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 *RemarketingListsUpdateCall) Do(opts ...googleapi.CallOption) (*RemarketingList, 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 := &RemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing remarketing list.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.remarketingLists.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/remarketingLists",
	//   "request": {
	//     "$ref": "RemarketingList"
	//   },
	//   "response": {
	//     "$ref": "RemarketingList"
	//   },
	//   "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

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

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves list of reports.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.reports.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "maxResults": {
	//       "default": "10",
	//       "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.",
	//       "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.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsRunCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsRunCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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": {
	//       "default": "false",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsCompatibleFieldsQueryCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsCompatibleFieldsQueryCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// Get: Retrieves a report file. This method supports media download.
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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsFilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsFilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a report file. This method supports media download.",
	//   "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
	header_      http.Header
}

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

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *ReportsFilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *ReportsFilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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": {
	//       "default": "10",
	//       "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.",
	//       "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of sites, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of sites, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SitesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SitesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SizesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SizesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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",
	//       "maximum": "32767",
	//       "minimum": "0",
	//       "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",
	//       "maximum": "32767",
	//       "minimum": "0",
	//       "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Gets a list of subaccounts, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets a list of subaccounts, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *SubaccountsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *SubaccountsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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.targetableRemarketingLists.get":

type TargetableRemarketingListsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one remarketing list by ID.
func (r *TargetableRemarketingListsService) Get(profileId int64, id int64) *TargetableRemarketingListsGetCall {
	c := &TargetableRemarketingListsGetCall{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 *TargetableRemarketingListsGetCall) Fields(s ...googleapi.Field) *TargetableRemarketingListsGetCall {
	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 *TargetableRemarketingListsGetCall) IfNoneMatch(entityTag string) *TargetableRemarketingListsGetCall {
	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 *TargetableRemarketingListsGetCall) Context(ctx context.Context) *TargetableRemarketingListsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetableRemarketingListsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetableRemarketingListsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/targetableRemarketingLists/{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.targetableRemarketingLists.get" call.
// Exactly one of *TargetableRemarketingList or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *TargetableRemarketingList.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 *TargetableRemarketingListsGetCall) Do(opts ...googleapi.CallOption) (*TargetableRemarketingList, 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 := &TargetableRemarketingList{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one remarketing list by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetableRemarketingLists.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Remarketing list 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}/targetableRemarketingLists/{id}",
	//   "response": {
	//     "$ref": "TargetableRemarketingList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetableRemarketingLists.list":

type TargetableRemarketingListsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of targetable remarketing lists, possibly
// filtered. This method supports paging.
func (r *TargetableRemarketingListsService) List(profileId int64, advertiserId int64) *TargetableRemarketingListsListCall {
	c := &TargetableRemarketingListsListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Active sets the optional parameter "active": Select only active or
// only inactive targetable remarketing lists.
func (c *TargetableRemarketingListsListCall) Active(active bool) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("active", fmt.Sprint(active))
	return c
}

// MaxResults sets the optional parameter "maxResults": Maximum number
// of results to return.
func (c *TargetableRemarketingListsListCall) MaxResults(maxResults int64) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// Name sets the optional parameter "name": Allows searching for objects
// by name or ID. Wildcards (*) are allowed. For example, "remarketing
// list*2015" will return objects with names like "remarketing list June
// 2015", "remarketing list April 2015", or simply "remarketing list
// 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 "remarketing list" will match objects with name "my remarketing
// list", "remarketing list 2015", or simply "remarketing list".
func (c *TargetableRemarketingListsListCall) Name(name string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("name", name)
	return c
}

// PageToken sets the optional parameter "pageToken": Value of the
// nextPageToken from the previous result page.
func (c *TargetableRemarketingListsListCall) PageToken(pageToken string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("pageToken", pageToken)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *TargetableRemarketingListsListCall) SortField(sortField string) *TargetableRemarketingListsListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *TargetableRemarketingListsListCall) SortOrder(sortOrder string) *TargetableRemarketingListsListCall {
	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 *TargetableRemarketingListsListCall) Fields(s ...googleapi.Field) *TargetableRemarketingListsListCall {
	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 *TargetableRemarketingListsListCall) IfNoneMatch(entityTag string) *TargetableRemarketingListsListCall {
	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 *TargetableRemarketingListsListCall) Context(ctx context.Context) *TargetableRemarketingListsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetableRemarketingListsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetableRemarketingListsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/targetableRemarketingLists")
	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.targetableRemarketingLists.list" call.
// Exactly one of *TargetableRemarketingListsListResponse or error will
// be non-nil. Any non-2xx status code is an error. Response headers are
// in either
// *TargetableRemarketingListsListResponse.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 *TargetableRemarketingListsListCall) Do(opts ...googleapi.CallOption) (*TargetableRemarketingListsListResponse, 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 := &TargetableRemarketingListsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of targetable remarketing lists, possibly filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetableRemarketingLists.list",
	//   "parameterOrder": [
	//     "profileId",
	//     "advertiserId"
	//   ],
	//   "parameters": {
	//     "active": {
	//       "description": "Select only active or only inactive targetable remarketing lists.",
	//       "location": "query",
	//       "type": "boolean"
	//     },
	//     "advertiserId": {
	//       "description": "Select only targetable remarketing lists targetable by these advertisers.",
	//       "format": "int64",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "type": "integer"
	//     },
	//     "name": {
	//       "description": "Allows searching for objects by name or ID. Wildcards (*) are allowed. For example, \"remarketing list*2015\" will return objects with names like \"remarketing list June 2015\", \"remarketing list April 2015\", or simply \"remarketing list 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 \"remarketing list\" will match objects with name \"my remarketing list\", \"remarketing list 2015\", or simply \"remarketing list\".",
	//       "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"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetableRemarketingLists",
	//   "response": {
	//     "$ref": "TargetableRemarketingListsListResponse"
	//   },
	//   "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 *TargetableRemarketingListsListCall) Pages(ctx context.Context, f func(*TargetableRemarketingListsListResponse) 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.targetingTemplates.get":

type TargetingTemplatesGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one targeting template by ID.
func (r *TargetingTemplatesService) Get(profileId int64, id int64) *TargetingTemplatesGetCall {
	c := &TargetingTemplatesGetCall{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 *TargetingTemplatesGetCall) Fields(s ...googleapi.Field) *TargetingTemplatesGetCall {
	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 *TargetingTemplatesGetCall) IfNoneMatch(entityTag string) *TargetingTemplatesGetCall {
	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 *TargetingTemplatesGetCall) Context(ctx context.Context) *TargetingTemplatesGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/targetingTemplates/{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.targetingTemplates.get" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.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 *TargetingTemplatesGetCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, 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 := &TargetingTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one targeting template by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetingTemplates.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Targeting template 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}/targetingTemplates/{id}",
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.insert":

type TargetingTemplatesInsertCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Insert: Inserts a new targeting template.
func (r *TargetingTemplatesService) Insert(profileId int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesInsertCall {
	c := &TargetingTemplatesInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.targetingtemplate = targetingtemplate
	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 *TargetingTemplatesInsertCall) Fields(s ...googleapi.Field) *TargetingTemplatesInsertCall {
	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 *TargetingTemplatesInsertCall) Context(ctx context.Context) *TargetingTemplatesInsertCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetingtemplate)
	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}/targetingTemplates")
	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.targetingTemplates.insert" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.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 *TargetingTemplatesInsertCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, 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 := &TargetingTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Inserts a new targeting template.",
	//   "httpMethod": "POST",
	//   "id": "dfareporting.targetingTemplates.insert",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.list":

type TargetingTemplatesListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Retrieves a list of targeting templates, optionally filtered.
// This method supports paging.
func (r *TargetingTemplatesService) List(profileId int64) *TargetingTemplatesListCall {
	c := &TargetingTemplatesListCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	return c
}

// AdvertiserId sets the optional parameter "advertiserId": Select only
// targeting templates with this advertiser ID.
func (c *TargetingTemplatesListCall) AdvertiserId(advertiserId int64) *TargetingTemplatesListCall {
	c.urlParams_.Set("advertiserId", fmt.Sprint(advertiserId))
	return c
}

// Ids sets the optional parameter "ids": Select only targeting
// templates with these IDs.
func (c *TargetingTemplatesListCall) Ids(ids ...int64) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) MaxResults(maxResults int64) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) PageToken(pageToken string) *TargetingTemplatesListCall {
	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, "template*2015" will return objects with names like
// "template June 2015", "template April 2015", or simply "template
// 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 "template" will match objects with name "my template", "template
// 2015", or simply "template".
func (c *TargetingTemplatesListCall) SearchString(searchString string) *TargetingTemplatesListCall {
	c.urlParams_.Set("searchString", searchString)
	return c
}

// SortField sets the optional parameter "sortField": Field by which to
// sort the list.
//
// Possible values:
//   "ID" (default)
//   "NAME"
func (c *TargetingTemplatesListCall) SortField(sortField string) *TargetingTemplatesListCall {
	c.urlParams_.Set("sortField", sortField)
	return c
}

// SortOrder sets the optional parameter "sortOrder": Order of sorted
// results.
//
// Possible values:
//   "ASCENDING" (default)
//   "DESCENDING"
func (c *TargetingTemplatesListCall) SortOrder(sortOrder string) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) Fields(s ...googleapi.Field) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) IfNoneMatch(entityTag string) *TargetingTemplatesListCall {
	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 *TargetingTemplatesListCall) Context(ctx context.Context) *TargetingTemplatesListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/targetingTemplates")
	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.targetingTemplates.list" call.
// Exactly one of *TargetingTemplatesListResponse or error will be
// non-nil. Any non-2xx status code is an error. Response headers are in
// either *TargetingTemplatesListResponse.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 *TargetingTemplatesListCall) Do(opts ...googleapi.CallOption) (*TargetingTemplatesListResponse, 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 := &TargetingTemplatesListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of targeting templates, optionally filtered. This method supports paging.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.targetingTemplates.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "advertiserId": {
	//       "description": "Select only targeting templates with this advertiser ID.",
	//       "format": "int64",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "ids": {
	//       "description": "Select only targeting templates with these IDs.",
	//       "format": "int64",
	//       "location": "query",
	//       "repeated": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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, \"template*2015\" will return objects with names like \"template June 2015\", \"template April 2015\", or simply \"template 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 \"template\" will match objects with name \"my template\", \"template 2015\", or simply \"template\".",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortField": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "enum": [
	//         "ASCENDING",
	//         "DESCENDING"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "response": {
	//     "$ref": "TargetingTemplatesListResponse"
	//   },
	//   "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 *TargetingTemplatesListCall) Pages(ctx context.Context, f func(*TargetingTemplatesListResponse) 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.targetingTemplates.patch":

type TargetingTemplatesPatchCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Updates an existing targeting template. This method supports
// patch semantics.
func (r *TargetingTemplatesService) Patch(profileId int64, id int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesPatchCall {
	c := &TargetingTemplatesPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.urlParams_.Set("id", fmt.Sprint(id))
	c.targetingtemplate = targetingtemplate
	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 *TargetingTemplatesPatchCall) Fields(s ...googleapi.Field) *TargetingTemplatesPatchCall {
	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 *TargetingTemplatesPatchCall) Context(ctx context.Context) *TargetingTemplatesPatchCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetingtemplate)
	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}/targetingTemplates")
	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.targetingTemplates.patch" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.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 *TargetingTemplatesPatchCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, 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 := &TargetingTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing targeting template. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "dfareporting.targetingTemplates.patch",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Targeting template 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}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.targetingTemplates.update":

type TargetingTemplatesUpdateCall struct {
	s                 *Service
	profileId         int64
	targetingtemplate *TargetingTemplate
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Updates an existing targeting template.
func (r *TargetingTemplatesService) Update(profileId int64, targetingtemplate *TargetingTemplate) *TargetingTemplatesUpdateCall {
	c := &TargetingTemplatesUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.profileId = profileId
	c.targetingtemplate = targetingtemplate
	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 *TargetingTemplatesUpdateCall) Fields(s ...googleapi.Field) *TargetingTemplatesUpdateCall {
	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 *TargetingTemplatesUpdateCall) Context(ctx context.Context) *TargetingTemplatesUpdateCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *TargetingTemplatesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *TargetingTemplatesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	reqHeaders.Set("User-Agent", c.s.userAgent())
	var body io.Reader = nil
	body, err := googleapi.WithoutDataWrapper.JSONReader(c.targetingtemplate)
	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}/targetingTemplates")
	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.targetingTemplates.update" call.
// Exactly one of *TargetingTemplate or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *TargetingTemplate.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 *TargetingTemplatesUpdateCall) Do(opts ...googleapi.CallOption) (*TargetingTemplate, 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 := &TargetingTemplate{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Updates an existing targeting template.",
	//   "httpMethod": "PUT",
	//   "id": "dfareporting.targetingTemplates.update",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/targetingTemplates",
	//   "request": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "response": {
	//     "$ref": "TargetingTemplate"
	//   },
	//   "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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserProfilesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserProfilesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserProfilesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserProfilesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionGroupsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionGroupsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionGroupsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionGroupsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolePermissionsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolePermissionsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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
	header_      http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_      http.Header
}

// List: Retrieves a list of user roles, possibly filtered. This method
// supports paging.
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" (default)
//   "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.
//
// Possible values:
//   "ASCENDING" (default)
//   "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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Retrieves a list of user roles, possibly filtered. This method supports paging.",
	//   "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": {
	//       "default": "1000",
	//       "description": "Maximum number of results to return.",
	//       "format": "int32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "0",
	//       "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": {
	//       "default": "ID",
	//       "description": "Field by which to sort the list.",
	//       "enum": [
	//         "ID",
	//         "NAME"
	//       ],
	//       "enumDescriptions": [
	//         "",
	//         ""
	//       ],
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "sortOrder": {
	//       "default": "ASCENDING",
	//       "description": "Order of sorted results.",
	//       "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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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
	header_    http.Header
}

// 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
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *UserRolesUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *UserRolesUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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 := gensupport.DecodeResponse(target, res); 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"
	//   ]
	// }

}

// method id "dfareporting.videoFormats.get":

type VideoFormatsGetCall struct {
	s            *Service
	profileId    int64
	id           int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Gets one video format by ID.
func (r *VideoFormatsService) Get(profileId int64, id int64) *VideoFormatsGetCall {
	c := &VideoFormatsGetCall{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 *VideoFormatsGetCall) Fields(s ...googleapi.Field) *VideoFormatsGetCall {
	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 *VideoFormatsGetCall) IfNoneMatch(entityTag string) *VideoFormatsGetCall {
	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 *VideoFormatsGetCall) Context(ctx context.Context) *VideoFormatsGetCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VideoFormatsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoFormatsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/videoFormats/{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.videoFormats.get" call.
// Exactly one of *VideoFormat or error will be non-nil. Any non-2xx
// status code is an error. Response headers are in either
// *VideoFormat.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 *VideoFormatsGetCall) Do(opts ...googleapi.CallOption) (*VideoFormat, 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 := &VideoFormat{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Gets one video format by ID.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.videoFormats.get",
	//   "parameterOrder": [
	//     "profileId",
	//     "id"
	//   ],
	//   "parameters": {
	//     "id": {
	//       "description": "Video format ID.",
	//       "format": "int32",
	//       "location": "path",
	//       "required": true,
	//       "type": "integer"
	//     },
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/videoFormats/{id}",
	//   "response": {
	//     "$ref": "VideoFormat"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}

// method id "dfareporting.videoFormats.list":

type VideoFormatsListCall struct {
	s            *Service
	profileId    int64
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// List: Lists available video formats.
func (r *VideoFormatsService) List(profileId int64) *VideoFormatsListCall {
	c := &VideoFormatsListCall{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 *VideoFormatsListCall) Fields(s ...googleapi.Field) *VideoFormatsListCall {
	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 *VideoFormatsListCall) IfNoneMatch(entityTag string) *VideoFormatsListCall {
	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 *VideoFormatsListCall) Context(ctx context.Context) *VideoFormatsListCall {
	c.ctx_ = ctx
	return c
}

// Header returns an http.Header that can be modified by the caller to
// add HTTP headers to the request.
func (c *VideoFormatsListCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *VideoFormatsListCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	for k, v := range c.header_ {
		reqHeaders[k] = v
	}
	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}/videoFormats")
	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.videoFormats.list" call.
// Exactly one of *VideoFormatsListResponse or error will be non-nil.
// Any non-2xx status code is an error. Response headers are in either
// *VideoFormatsListResponse.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 *VideoFormatsListCall) Do(opts ...googleapi.CallOption) (*VideoFormatsListResponse, 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 := &VideoFormatsListResponse{
		ServerResponse: googleapi.ServerResponse{
			Header:         res.Header,
			HTTPStatusCode: res.StatusCode,
		},
	}
	target := &ret
	if err := gensupport.DecodeResponse(target, res); err != nil {
		return nil, err
	}
	return ret, nil
	// {
	//   "description": "Lists available video formats.",
	//   "httpMethod": "GET",
	//   "id": "dfareporting.videoFormats.list",
	//   "parameterOrder": [
	//     "profileId"
	//   ],
	//   "parameters": {
	//     "profileId": {
	//       "description": "User profile ID associated with this request.",
	//       "format": "int64",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "userprofiles/{profileId}/videoFormats",
	//   "response": {
	//     "$ref": "VideoFormatsListResponse"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/dfatrafficking"
	//   ]
	// }

}
