// Copyright 2020 Google LLC.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Code generated file. DO NOT EDIT.

// Package licensing provides access to the Licensing API.
//
// For product documentation, see: https://developers.google.com/admin-sdk/licensing/
//
// Creating a client
//
// Usage example:
//
//   import "google.golang.org/api/licensing/v1"
//   ...
//   ctx := context.Background()
//   licensingService, err := licensing.NewService(ctx)
//
// In this example, Google Application Default Credentials are used for authentication.
//
// For information on how to create and obtain Application Default Credentials, see https://developers.google.com/identity/protocols/application-default-credentials.
//
// Other authentication options
//
// To use an API key for authentication (note: some APIs do not support API keys), use option.WithAPIKey:
//
//   licensingService, err := licensing.NewService(ctx, option.WithAPIKey("AIza..."))
//
// To use an OAuth token (e.g., a user token obtained via a three-legged OAuth flow), use option.WithTokenSource:
//
//   config := &oauth2.Config{...}
//   // ...
//   token, err := config.Exchange(ctx, ...)
//   licensingService, err := licensing.NewService(ctx, option.WithTokenSource(config.TokenSource(ctx, token)))
//
// See https://godoc.org/google.golang.org/api/option/ for details on options.
package licensing // import "google.golang.org/api/licensing/v1"

import (
	"bytes"
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strconv"
	"strings"

	googleapi "google.golang.org/api/googleapi"
	gensupport "google.golang.org/api/internal/gensupport"
	option "google.golang.org/api/option"
	internaloption "google.golang.org/api/option/internaloption"
	htransport "google.golang.org/api/transport/http"
)

// 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 _ = internaloption.WithDefaultEndpoint

const apiId = "licensing:v1"
const apiName = "licensing"
const apiVersion = "v1"
const basePath = "https://www.googleapis.com/apps/licensing/v1/product/"

// OAuth2 scopes used by this API.
const (
	// View and manage G Suite licenses for your domain
	AppsLicensingScope = "https://www.googleapis.com/auth/apps.licensing"
)

// NewService creates a new Service.
func NewService(ctx context.Context, opts ...option.ClientOption) (*Service, error) {
	scopesOption := option.WithScopes(
		"https://www.googleapis.com/auth/apps.licensing",
	)
	// NOTE: prepend, so we don't override user-specified scopes.
	opts = append([]option.ClientOption{scopesOption}, opts...)
	opts = append(opts, internaloption.WithDefaultEndpoint(basePath))
	client, endpoint, err := htransport.NewClient(ctx, opts...)
	if err != nil {
		return nil, err
	}
	s, err := New(client)
	if err != nil {
		return nil, err
	}
	if endpoint != "" {
		s.BasePath = endpoint
	}
	return s, nil
}

// New creates a new Service. It uses the provided http.Client for requests.
//
// Deprecated: please use NewService instead.
// To provide a custom HTTP client, use option.WithHTTPClient.
// If you are using google.golang.org/api/googleapis/transport.APIKey, use option.WithAPIKey with NewService instead.
func New(client *http.Client) (*Service, error) {
	if client == nil {
		return nil, errors.New("client is nil")
	}
	s := &Service{client: client, BasePath: basePath}
	s.LicenseAssignments = NewLicenseAssignmentsService(s)
	return s, nil
}

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

	LicenseAssignments *LicenseAssignmentsService
}

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

func NewLicenseAssignmentsService(s *Service) *LicenseAssignmentsService {
	rs := &LicenseAssignmentsService{s: s}
	return rs
}

type LicenseAssignmentsService struct {
	s *Service
}

// LicenseAssignment: Representation of a license assignment.
type LicenseAssignment struct {
	// Etags: ETag of the resource.
	Etags string `json:"etags,omitempty"`

	// Kind: Identifies the resource as a LicenseAssignment.
	Kind string `json:"kind,omitempty"`

	// ProductId: A product's unique identifier. For more information about
	// products in this version of the API, see Product and SKU IDs.
	ProductId string `json:"productId,omitempty"`

	// ProductName: Display Name of the product.
	ProductName string `json:"productName,omitempty"`

	// SelfLink: Link to this page.
	SelfLink string `json:"selfLink,omitempty"`

	// SkuId: A product SKU's unique identifier. For more information about
	// available SKUs in this version of the API, see Products and SKUs.
	SkuId string `json:"skuId,omitempty"`

	// SkuName: Display Name of the sku of the product.
	SkuName string `json:"skuName,omitempty"`

	// UserId: The user's current primary email address. If the user's email
	// address changes, use the new email address in your API requests.
	// Since a userId is subject to change, do not use a userId value as a
	// key for persistent data. This key could break if the current user's
	// email address changes. If the userId is suspended, the license status
	// changes.
	UserId string `json:"userId,omitempty"`

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

	// ForceSendFields is a list of field names (e.g. "Etags") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "Etags") 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 *LicenseAssignment) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseAssignment
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LicenseAssignmentInsert: Representation of a license assignment.
type LicenseAssignmentInsert struct {
	// UserId: Email id of the user
	UserId string `json:"userId,omitempty"`

	// ForceSendFields is a list of field names (e.g. "UserId") to
	// unconditionally include in API requests. By default, fields with
	// empty values are omitted from API requests. However, any non-pointer,
	// non-interface field appearing in ForceSendFields will be sent to the
	// 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. "UserId") 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 *LicenseAssignmentInsert) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseAssignmentInsert
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// LicenseAssignmentList: LicesnseAssignment List for a given
// product/sku for a customer.
type LicenseAssignmentList struct {
	// Etag: ETag of the resource.
	Etag string `json:"etag,omitempty"`

	// Items: The LicenseAssignments in this page of results.
	Items []*LicenseAssignment `json:"items,omitempty"`

	// Kind: Identifies the resource as a collection of LicenseAssignments.
	Kind string `json:"kind,omitempty"`

	// NextPageToken: The token that you must submit in a subsequent request
	// to retrieve additional license results matching your query
	// parameters. The maxResults query string is related to the
	// nextPageToken since maxResults determines how many entries are
	// returned on each next page.
	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 *LicenseAssignmentList) MarshalJSON() ([]byte, error) {
	type NoMethod LicenseAssignmentList
	raw := NoMethod(*s)
	return gensupport.MarshalJSON(raw, s.ForceSendFields, s.NullFields)
}

// method id "licensing.licenseAssignments.delete":

type LicenseAssignmentsDeleteCall struct {
	s          *Service
	productId  string
	skuId      string
	userId     string
	urlParams_ gensupport.URLParams
	ctx_       context.Context
	header_    http.Header
}

// Delete: Revoke a license.
func (r *LicenseAssignmentsService) Delete(productId string, skuId string, userId string) *LicenseAssignmentsDeleteCall {
	c := &LicenseAssignmentsDeleteCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.userId = userId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseAssignmentsDeleteCall) Fields(s ...googleapi.Field) *LicenseAssignmentsDeleteCall {
	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 *LicenseAssignmentsDeleteCall) Context(ctx context.Context) *LicenseAssignmentsDeleteCall {
	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 *LicenseAssignmentsDeleteCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsDeleteCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/user/{userId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("DELETE", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
		"userId":    c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.delete" call.
func (c *LicenseAssignmentsDeleteCall) 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": "Revoke a license.",
	//   "httpMethod": "DELETE",
	//   "id": "licensing.licenseAssignments.delete",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId",
	//     "userId"
	//   ],
	//   "parameters": {
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The user's current primary email address. If the user's email address changes, use the new email address in your API requests.\nSince a userId is subject to change, do not use a userId value as a key for persistent data. This key could break if the current user's email address changes.\nIf the userId is suspended, the license status changes.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/user/{userId}",
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// method id "licensing.licenseAssignments.get":

type LicenseAssignmentsGetCall struct {
	s            *Service
	productId    string
	skuId        string
	userId       string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// Get: Get a specific user's license by product SKU.
func (r *LicenseAssignmentsService) Get(productId string, skuId string, userId string) *LicenseAssignmentsGetCall {
	c := &LicenseAssignmentsGetCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.userId = userId
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseAssignmentsGetCall) Fields(s ...googleapi.Field) *LicenseAssignmentsGetCall {
	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 *LicenseAssignmentsGetCall) IfNoneMatch(entityTag string) *LicenseAssignmentsGetCall {
	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 *LicenseAssignmentsGetCall) Context(ctx context.Context) *LicenseAssignmentsGetCall {
	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 *LicenseAssignmentsGetCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsGetCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/user/{userId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
		"userId":    c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.get" call.
// Exactly one of *LicenseAssignment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignment.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsGetCall) Do(opts ...googleapi.CallOption) (*LicenseAssignment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignment{
		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": "Get a specific user's license by product SKU.",
	//   "httpMethod": "GET",
	//   "id": "licensing.licenseAssignments.get",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId",
	//     "userId"
	//   ],
	//   "parameters": {
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The user's current primary email address. If the user's email address changes, use the new email address in your API requests.\nSince a userId is subject to change, do not use a userId value as a key for persistent data. This key could break if the current user's email address changes.\nIf the userId is suspended, the license status changes.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/user/{userId}",
	//   "response": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// method id "licensing.licenseAssignments.insert":

type LicenseAssignmentsInsertCall struct {
	s                       *Service
	productId               string
	skuId                   string
	licenseassignmentinsert *LicenseAssignmentInsert
	urlParams_              gensupport.URLParams
	ctx_                    context.Context
	header_                 http.Header
}

// Insert: Assign a license.
func (r *LicenseAssignmentsService) Insert(productId string, skuId string, licenseassignmentinsert *LicenseAssignmentInsert) *LicenseAssignmentsInsertCall {
	c := &LicenseAssignmentsInsertCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.licenseassignmentinsert = licenseassignmentinsert
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseAssignmentsInsertCall) Fields(s ...googleapi.Field) *LicenseAssignmentsInsertCall {
	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 *LicenseAssignmentsInsertCall) Context(ctx context.Context) *LicenseAssignmentsInsertCall {
	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 *LicenseAssignmentsInsertCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsInsertCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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.licenseassignmentinsert)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/user")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("POST", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.insert" call.
// Exactly one of *LicenseAssignment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignment.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsInsertCall) Do(opts ...googleapi.CallOption) (*LicenseAssignment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignment{
		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": "Assign a license.",
	//   "httpMethod": "POST",
	//   "id": "licensing.licenseAssignments.insert",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId"
	//   ],
	//   "parameters": {
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/user",
	//   "request": {
	//     "$ref": "LicenseAssignmentInsert"
	//   },
	//   "response": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// method id "licensing.licenseAssignments.listForProduct":

type LicenseAssignmentsListForProductCall struct {
	s            *Service
	productId    string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListForProduct: List all users assigned licenses for a specific
// product SKU.
func (r *LicenseAssignmentsService) ListForProduct(productId string, customerId string) *LicenseAssignmentsListForProductCall {
	c := &LicenseAssignmentsListForProductCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.urlParams_.Set("customerId", customerId)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maxResults
// query string determines how many entries are returned on each page of
// a large response. This is an optional parameter. The value must be a
// positive number.
func (c *LicenseAssignmentsListForProductCall) MaxResults(maxResults int64) *LicenseAssignmentsListForProductCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to fetch the
// next page of data. The maxResults query string is related to the
// pageToken since maxResults determines how many entries are returned
// on each page. This is an optional query string. If not specified, the
// server returns the first page.
func (c *LicenseAssignmentsListForProductCall) PageToken(pageToken string) *LicenseAssignmentsListForProductCall {
	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 *LicenseAssignmentsListForProductCall) Fields(s ...googleapi.Field) *LicenseAssignmentsListForProductCall {
	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 *LicenseAssignmentsListForProductCall) IfNoneMatch(entityTag string) *LicenseAssignmentsListForProductCall {
	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 *LicenseAssignmentsListForProductCall) Context(ctx context.Context) *LicenseAssignmentsListForProductCall {
	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 *LicenseAssignmentsListForProductCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsListForProductCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/users")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.listForProduct" call.
// Exactly one of *LicenseAssignmentList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignmentList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsListForProductCall) Do(opts ...googleapi.CallOption) (*LicenseAssignmentList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignmentList{
		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": "List all users assigned licenses for a specific product SKU.",
	//   "httpMethod": "GET",
	//   "id": "licensing.licenseAssignments.listForProduct",
	//   "parameterOrder": [
	//     "productId",
	//     "customerId"
	//   ],
	//   "parameters": {
	//     "customerId": {
	//       "description": "Customer's customerId. A previous version of this API accepted the primary domain name as a value for this field.\nIf the customer is suspended, the server returns an error.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "100",
	//       "description": "The maxResults query string determines how many entries are returned on each page of a large response. This is an optional parameter. The value must be a positive number.",
	//       "format": "uint32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "1",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "default": "",
	//       "description": "Token to fetch the next page of data. The maxResults query string is related to the pageToken since maxResults determines how many entries are returned on each page. This is an optional query string. If not specified, the server returns the first page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/users",
	//   "response": {
	//     "$ref": "LicenseAssignmentList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// 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 *LicenseAssignmentsListForProductCall) Pages(ctx context.Context, f func(*LicenseAssignmentList) 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 "licensing.licenseAssignments.listForProductAndSku":

type LicenseAssignmentsListForProductAndSkuCall struct {
	s            *Service
	productId    string
	skuId        string
	urlParams_   gensupport.URLParams
	ifNoneMatch_ string
	ctx_         context.Context
	header_      http.Header
}

// ListForProductAndSku: List all users assigned licenses for a specific
// product SKU.
func (r *LicenseAssignmentsService) ListForProductAndSku(productId string, skuId string, customerId string) *LicenseAssignmentsListForProductAndSkuCall {
	c := &LicenseAssignmentsListForProductAndSkuCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.urlParams_.Set("customerId", customerId)
	return c
}

// MaxResults sets the optional parameter "maxResults": The maxResults
// query string determines how many entries are returned on each page of
// a large response. This is an optional parameter. The value must be a
// positive number.
func (c *LicenseAssignmentsListForProductAndSkuCall) MaxResults(maxResults int64) *LicenseAssignmentsListForProductAndSkuCall {
	c.urlParams_.Set("maxResults", fmt.Sprint(maxResults))
	return c
}

// PageToken sets the optional parameter "pageToken": Token to fetch the
// next page of data. The maxResults query string is related to the
// pageToken since maxResults determines how many entries are returned
// on each page. This is an optional query string. If not specified, the
// server returns the first page.
func (c *LicenseAssignmentsListForProductAndSkuCall) PageToken(pageToken string) *LicenseAssignmentsListForProductAndSkuCall {
	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 *LicenseAssignmentsListForProductAndSkuCall) Fields(s ...googleapi.Field) *LicenseAssignmentsListForProductAndSkuCall {
	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 *LicenseAssignmentsListForProductAndSkuCall) IfNoneMatch(entityTag string) *LicenseAssignmentsListForProductAndSkuCall {
	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 *LicenseAssignmentsListForProductAndSkuCall) Context(ctx context.Context) *LicenseAssignmentsListForProductAndSkuCall {
	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 *LicenseAssignmentsListForProductAndSkuCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsListForProductAndSkuCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/users")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("GET", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.listForProductAndSku" call.
// Exactly one of *LicenseAssignmentList or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignmentList.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsListForProductAndSkuCall) Do(opts ...googleapi.CallOption) (*LicenseAssignmentList, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignmentList{
		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": "List all users assigned licenses for a specific product SKU.",
	//   "httpMethod": "GET",
	//   "id": "licensing.licenseAssignments.listForProductAndSku",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId",
	//     "customerId"
	//   ],
	//   "parameters": {
	//     "customerId": {
	//       "description": "Customer's customerId. A previous version of this API accepted the primary domain name as a value for this field.\nIf the customer is suspended, the server returns an error.",
	//       "location": "query",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "maxResults": {
	//       "default": "100",
	//       "description": "The maxResults query string determines how many entries are returned on each page of a large response. This is an optional parameter. The value must be a positive number.",
	//       "format": "uint32",
	//       "location": "query",
	//       "maximum": "1000",
	//       "minimum": "1",
	//       "type": "integer"
	//     },
	//     "pageToken": {
	//       "default": "",
	//       "description": "Token to fetch the next page of data. The maxResults query string is related to the pageToken since maxResults determines how many entries are returned on each page. This is an optional query string. If not specified, the server returns the first page.",
	//       "location": "query",
	//       "type": "string"
	//     },
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/users",
	//   "response": {
	//     "$ref": "LicenseAssignmentList"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// 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 *LicenseAssignmentsListForProductAndSkuCall) Pages(ctx context.Context, f func(*LicenseAssignmentList) 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 "licensing.licenseAssignments.patch":

type LicenseAssignmentsPatchCall struct {
	s                 *Service
	productId         string
	skuId             string
	userId            string
	licenseassignment *LicenseAssignment
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Patch: Reassign a user's product SKU with a different SKU in the same
// product. This method supports patch semantics.
func (r *LicenseAssignmentsService) Patch(productId string, skuId string, userId string, licenseassignment *LicenseAssignment) *LicenseAssignmentsPatchCall {
	c := &LicenseAssignmentsPatchCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.userId = userId
	c.licenseassignment = licenseassignment
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseAssignmentsPatchCall) Fields(s ...googleapi.Field) *LicenseAssignmentsPatchCall {
	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 *LicenseAssignmentsPatchCall) Context(ctx context.Context) *LicenseAssignmentsPatchCall {
	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 *LicenseAssignmentsPatchCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsPatchCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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.licenseassignment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/user/{userId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PATCH", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
		"userId":    c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.patch" call.
// Exactly one of *LicenseAssignment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignment.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsPatchCall) Do(opts ...googleapi.CallOption) (*LicenseAssignment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignment{
		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": "Reassign a user's product SKU with a different SKU in the same product. This method supports patch semantics.",
	//   "httpMethod": "PATCH",
	//   "id": "licensing.licenseAssignments.patch",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId",
	//     "userId"
	//   ],
	//   "parameters": {
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The user's current primary email address. If the user's email address changes, use the new email address in your API requests.\nSince a userId is subject to change, do not use a userId value as a key for persistent data. This key could break if the current user's email address changes.\nIf the userId is suspended, the license status changes.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/user/{userId}",
	//   "request": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "response": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}

// method id "licensing.licenseAssignments.update":

type LicenseAssignmentsUpdateCall struct {
	s                 *Service
	productId         string
	skuId             string
	userId            string
	licenseassignment *LicenseAssignment
	urlParams_        gensupport.URLParams
	ctx_              context.Context
	header_           http.Header
}

// Update: Reassign a user's product SKU with a different SKU in the
// same product.
func (r *LicenseAssignmentsService) Update(productId string, skuId string, userId string, licenseassignment *LicenseAssignment) *LicenseAssignmentsUpdateCall {
	c := &LicenseAssignmentsUpdateCall{s: r.s, urlParams_: make(gensupport.URLParams)}
	c.productId = productId
	c.skuId = skuId
	c.userId = userId
	c.licenseassignment = licenseassignment
	return c
}

// Fields allows partial responses to be retrieved. See
// https://developers.google.com/gdata/docs/2.0/basics#PartialResponse
// for more information.
func (c *LicenseAssignmentsUpdateCall) Fields(s ...googleapi.Field) *LicenseAssignmentsUpdateCall {
	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 *LicenseAssignmentsUpdateCall) Context(ctx context.Context) *LicenseAssignmentsUpdateCall {
	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 *LicenseAssignmentsUpdateCall) Header() http.Header {
	if c.header_ == nil {
		c.header_ = make(http.Header)
	}
	return c.header_
}

func (c *LicenseAssignmentsUpdateCall) doRequest(alt string) (*http.Response, error) {
	reqHeaders := make(http.Header)
	reqHeaders.Set("x-goog-api-client", "gl-go/1.11.0 gdcl/20200225")
	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.licenseassignment)
	if err != nil {
		return nil, err
	}
	reqHeaders.Set("Content-Type", "application/json")
	c.urlParams_.Set("alt", alt)
	c.urlParams_.Set("prettyPrint", "false")
	urls := googleapi.ResolveRelative(c.s.BasePath, "{productId}/sku/{skuId}/user/{userId}")
	urls += "?" + c.urlParams_.Encode()
	req, err := http.NewRequest("PUT", urls, body)
	if err != nil {
		return nil, err
	}
	req.Header = reqHeaders
	googleapi.Expand(req.URL, map[string]string{
		"productId": c.productId,
		"skuId":     c.skuId,
		"userId":    c.userId,
	})
	return gensupport.SendRequest(c.ctx_, c.s.client, req)
}

// Do executes the "licensing.licenseAssignments.update" call.
// Exactly one of *LicenseAssignment or error will be non-nil. Any
// non-2xx status code is an error. Response headers are in either
// *LicenseAssignment.ServerResponse.Header or (if a response was
// returned at all) in error.(*googleapi.Error).Header. Use
// googleapi.IsNotModified to check whether the returned error was
// because http.StatusNotModified was returned.
func (c *LicenseAssignmentsUpdateCall) Do(opts ...googleapi.CallOption) (*LicenseAssignment, error) {
	gensupport.SetOptions(c.urlParams_, opts...)
	res, err := c.doRequest("json")
	if res != nil && res.StatusCode == http.StatusNotModified {
		if res.Body != nil {
			res.Body.Close()
		}
		return nil, &googleapi.Error{
			Code:   res.StatusCode,
			Header: res.Header,
		}
	}
	if err != nil {
		return nil, err
	}
	defer googleapi.CloseBody(res)
	if err := googleapi.CheckResponse(res); err != nil {
		return nil, err
	}
	ret := &LicenseAssignment{
		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": "Reassign a user's product SKU with a different SKU in the same product.",
	//   "httpMethod": "PUT",
	//   "id": "licensing.licenseAssignments.update",
	//   "parameterOrder": [
	//     "productId",
	//     "skuId",
	//     "userId"
	//   ],
	//   "parameters": {
	//     "productId": {
	//       "description": "A product's unique identifier. For more information about products in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "skuId": {
	//       "description": "A product SKU's unique identifier. For more information about available SKUs in this version of the API, see Products and SKUs.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     },
	//     "userId": {
	//       "description": "The user's current primary email address. If the user's email address changes, use the new email address in your API requests.\nSince a userId is subject to change, do not use a userId value as a key for persistent data. This key could break if the current user's email address changes.\nIf the userId is suspended, the license status changes.",
	//       "location": "path",
	//       "required": true,
	//       "type": "string"
	//     }
	//   },
	//   "path": "{productId}/sku/{skuId}/user/{userId}",
	//   "request": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "response": {
	//     "$ref": "LicenseAssignment"
	//   },
	//   "scopes": [
	//     "https://www.googleapis.com/auth/apps.licensing"
	//   ]
	// }

}
