package storagecache

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
//
// Code generated by Microsoft (R) AutoRest Code Generator.
// Changes may cause incorrect behavior and will be lost if the code is regenerated.

import (
	"context"
	"encoding/json"
	"github.com/Azure/go-autorest/autorest"
	"github.com/Azure/go-autorest/autorest/azure"
	"github.com/Azure/go-autorest/autorest/date"
	"github.com/Azure/go-autorest/autorest/to"
	"github.com/Azure/go-autorest/tracing"
	"net/http"
)

// The package's fully qualified name.
const fqdn = "github.com/Azure/azure-sdk-for-go/services/storagecache/mgmt/2020-10-01/storagecache"

// APIOperation REST API operation description: see
// https://github.com/Azure/azure-rest-api-specs/blob/master/documentation/openapi-authoring-automated-guidelines.md#r3023-operationsapiimplementation
type APIOperation struct {
	// Display - The object that represents the operation.
	Display *APIOperationDisplay `json:"display,omitempty"`
	// Origin - Origin of the operation.
	Origin *string `json:"origin,omitempty"`
	// IsDataAction - The flag that indicates whether the operation applies to data plane.
	IsDataAction *bool `json:"isDataAction,omitempty"`
	// Name - Operation name: {provider}/{resource}/{operation}
	Name *string `json:"name,omitempty"`
	// APIOperationProperties - Additional details about an operation.
	*APIOperationProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for APIOperation.
func (ao APIOperation) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ao.Display != nil {
		objectMap["display"] = ao.Display
	}
	if ao.Origin != nil {
		objectMap["origin"] = ao.Origin
	}
	if ao.IsDataAction != nil {
		objectMap["isDataAction"] = ao.IsDataAction
	}
	if ao.Name != nil {
		objectMap["name"] = ao.Name
	}
	if ao.APIOperationProperties != nil {
		objectMap["properties"] = ao.APIOperationProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for APIOperation struct.
func (ao *APIOperation) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "display":
			if v != nil {
				var display APIOperationDisplay
				err = json.Unmarshal(*v, &display)
				if err != nil {
					return err
				}
				ao.Display = &display
			}
		case "origin":
			if v != nil {
				var origin string
				err = json.Unmarshal(*v, &origin)
				if err != nil {
					return err
				}
				ao.Origin = &origin
			}
		case "isDataAction":
			if v != nil {
				var isDataAction bool
				err = json.Unmarshal(*v, &isDataAction)
				if err != nil {
					return err
				}
				ao.IsDataAction = &isDataAction
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ao.Name = &name
			}
		case "properties":
			if v != nil {
				var APIOperationProperties APIOperationProperties
				err = json.Unmarshal(*v, &APIOperationProperties)
				if err != nil {
					return err
				}
				ao.APIOperationProperties = &APIOperationProperties
			}
		}
	}

	return nil
}

// APIOperationDisplay the object that represents the operation.
type APIOperationDisplay struct {
	// Operation - Operation type: Read, write, delete, etc.
	Operation *string `json:"operation,omitempty"`
	// Provider - Service provider: Microsoft.StorageCache
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed: Cache, etc.
	Resource *string `json:"resource,omitempty"`
	// Description - The description of the operation
	Description *string `json:"description,omitempty"`
}

// APIOperationListResult result of the request to list Resource Provider operations. It contains a list of
// operations and a URL link to get the next set of results.
type APIOperationListResult struct {
	autorest.Response `json:"-"`
	// NextLink - URL to get the next set of operation list results if there are any.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - List of Resource Provider operations supported by the Microsoft.StorageCache resource provider.
	Value *[]APIOperation `json:"value,omitempty"`
}

// APIOperationListResultIterator provides access to a complete listing of APIOperation values.
type APIOperationListResultIterator struct {
	i    int
	page APIOperationListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *APIOperationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/APIOperationListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *APIOperationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter APIOperationListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter APIOperationListResultIterator) Response() APIOperationListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter APIOperationListResultIterator) Value() APIOperation {
	if !iter.page.NotDone() {
		return APIOperation{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the APIOperationListResultIterator type.
func NewAPIOperationListResultIterator(page APIOperationListResultPage) APIOperationListResultIterator {
	return APIOperationListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (aolr APIOperationListResult) IsEmpty() bool {
	return aolr.Value == nil || len(*aolr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (aolr APIOperationListResult) hasNextLink() bool {
	return aolr.NextLink != nil && len(*aolr.NextLink) != 0
}

// aPIOperationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (aolr APIOperationListResult) aPIOperationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !aolr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(aolr.NextLink)))
}

// APIOperationListResultPage contains a page of APIOperation values.
type APIOperationListResultPage struct {
	fn   func(context.Context, APIOperationListResult) (APIOperationListResult, error)
	aolr APIOperationListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *APIOperationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/APIOperationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.aolr)
		if err != nil {
			return err
		}
		page.aolr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *APIOperationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page APIOperationListResultPage) NotDone() bool {
	return !page.aolr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page APIOperationListResultPage) Response() APIOperationListResult {
	return page.aolr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page APIOperationListResultPage) Values() []APIOperation {
	if page.aolr.IsEmpty() {
		return nil
	}
	return *page.aolr.Value
}

// Creates a new instance of the APIOperationListResultPage type.
func NewAPIOperationListResultPage(cur APIOperationListResult, getNextPage func(context.Context, APIOperationListResult) (APIOperationListResult, error)) APIOperationListResultPage {
	return APIOperationListResultPage{
		fn:   getNextPage,
		aolr: cur,
	}
}

// APIOperationProperties additional details about an operation.
type APIOperationProperties struct {
	// ServiceSpecification - Specification of the all the metrics provided for a resource type.
	ServiceSpecification *APIOperationPropertiesServiceSpecification `json:"serviceSpecification,omitempty"`
}

// APIOperationPropertiesServiceSpecification specification of the all the metrics provided for a resource
// type.
type APIOperationPropertiesServiceSpecification struct {
	// MetricSpecifications - Details about operations related to metrics.
	MetricSpecifications *[]MetricSpecification `json:"metricSpecifications,omitempty"`
}

// AscOperation the status of operation.
type AscOperation struct {
	autorest.Response `json:"-"`
	// ID - The operation Id.
	ID *string `json:"id,omitempty"`
	// Name - The operation name.
	Name *string `json:"name,omitempty"`
	// StartTime - The start time of the operation.
	StartTime *string `json:"startTime,omitempty"`
	// EndTime - The end time of the operation.
	EndTime *string `json:"endTime,omitempty"`
	// Status - The status of the operation.
	Status *string `json:"status,omitempty"`
	// Error - The error detail of the operation if any.
	Error *ErrorResponse `json:"error,omitempty"`
	// AscOperationProperties - Additional operation specific properties
	*AscOperationProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for AscOperation.
func (ao AscOperation) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ao.ID != nil {
		objectMap["id"] = ao.ID
	}
	if ao.Name != nil {
		objectMap["name"] = ao.Name
	}
	if ao.StartTime != nil {
		objectMap["startTime"] = ao.StartTime
	}
	if ao.EndTime != nil {
		objectMap["endTime"] = ao.EndTime
	}
	if ao.Status != nil {
		objectMap["status"] = ao.Status
	}
	if ao.Error != nil {
		objectMap["error"] = ao.Error
	}
	if ao.AscOperationProperties != nil {
		objectMap["properties"] = ao.AscOperationProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for AscOperation struct.
func (ao *AscOperation) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ao.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ao.Name = &name
			}
		case "startTime":
			if v != nil {
				var startTime string
				err = json.Unmarshal(*v, &startTime)
				if err != nil {
					return err
				}
				ao.StartTime = &startTime
			}
		case "endTime":
			if v != nil {
				var endTime string
				err = json.Unmarshal(*v, &endTime)
				if err != nil {
					return err
				}
				ao.EndTime = &endTime
			}
		case "status":
			if v != nil {
				var status string
				err = json.Unmarshal(*v, &status)
				if err != nil {
					return err
				}
				ao.Status = &status
			}
		case "error":
			if v != nil {
				var errorVar ErrorResponse
				err = json.Unmarshal(*v, &errorVar)
				if err != nil {
					return err
				}
				ao.Error = &errorVar
			}
		case "properties":
			if v != nil {
				var ascOperationProperties AscOperationProperties
				err = json.Unmarshal(*v, &ascOperationProperties)
				if err != nil {
					return err
				}
				ao.AscOperationProperties = &ascOperationProperties
			}
		}
	}

	return nil
}

// AscOperationProperties operation specific output
type AscOperationProperties struct {
	// Output - Additional Operation Specific Properties
	Output map[string]interface{} `json:"output"`
}

// MarshalJSON is the custom marshaler for AscOperationProperties.
func (aop AscOperationProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if aop.Output != nil {
		objectMap["output"] = aop.Output
	}
	return json.Marshal(objectMap)
}

// Cache a Cache instance. Follows Azure Resource Manager standards:
// https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/resource-api-reference.md
type Cache struct {
	autorest.Response `json:"-"`
	// Tags - ARM tags as name/value pairs.
	Tags interface{} `json:"tags,omitempty"`
	// ID - READ-ONLY; Resource ID of the Cache.
	ID *string `json:"id,omitempty"`
	// Location - Region name string.
	Location *string `json:"location,omitempty"`
	// Name - READ-ONLY; Name of Cache.
	Name *string `json:"name,omitempty"`
	// Type - READ-ONLY; Type of the Cache; Microsoft.StorageCache/Cache
	Type *string `json:"type,omitempty"`
	// Identity - The identity of the cache, if configured.
	Identity *CacheIdentity `json:"identity,omitempty"`
	// SystemData - READ-ONLY; The system meta data relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
	// CacheProperties - Properties of the Cache.
	*CacheProperties `json:"properties,omitempty"`
	// Sku - SKU for the Cache.
	Sku *CacheSku `json:"sku,omitempty"`
}

// MarshalJSON is the custom marshaler for Cache.
func (c Cache) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if c.Tags != nil {
		objectMap["tags"] = c.Tags
	}
	if c.Location != nil {
		objectMap["location"] = c.Location
	}
	if c.Identity != nil {
		objectMap["identity"] = c.Identity
	}
	if c.CacheProperties != nil {
		objectMap["properties"] = c.CacheProperties
	}
	if c.Sku != nil {
		objectMap["sku"] = c.Sku
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Cache struct.
func (c *Cache) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "tags":
			if v != nil {
				var tags interface{}
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				c.Tags = tags
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				c.ID = &ID
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				c.Location = &location
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				c.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				c.Type = &typeVar
			}
		case "identity":
			if v != nil {
				var identity CacheIdentity
				err = json.Unmarshal(*v, &identity)
				if err != nil {
					return err
				}
				c.Identity = &identity
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				c.SystemData = &systemData
			}
		case "properties":
			if v != nil {
				var cacheProperties CacheProperties
				err = json.Unmarshal(*v, &cacheProperties)
				if err != nil {
					return err
				}
				c.CacheProperties = &cacheProperties
			}
		case "sku":
			if v != nil {
				var sku CacheSku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				c.Sku = &sku
			}
		}
	}

	return nil
}

// CacheActiveDirectorySettings active Directory settings used to join a cache to a domain.
type CacheActiveDirectorySettings struct {
	// PrimaryDNSIPAddress - Primary DNS IP address used to resolve the Active Directory domain controller's fully qualified domain name.
	PrimaryDNSIPAddress *string `json:"primaryDnsIpAddress,omitempty"`
	// SecondaryDNSIPAddress - Secondary DNS IP address used to resolve the Active Directory domain controller's fully qualified domain name.
	SecondaryDNSIPAddress *string `json:"secondaryDnsIpAddress,omitempty"`
	// DomainName - The fully qualified domain name of the Active Directory domain controller.
	DomainName *string `json:"domainName,omitempty"`
	// DomainNetBiosName - The Active Directory domain's NetBIOS name.
	DomainNetBiosName *string `json:"domainNetBiosName,omitempty"`
	// CacheNetBiosName - The NetBIOS name to assign to the HPC Cache when it joins the Active Directory domain as a server. Length must 1-15 characters from the class [-0-9a-zA-Z].
	CacheNetBiosName *string `json:"cacheNetBiosName,omitempty"`
	// DomainJoined - READ-ONLY; True if the HPC Cache is joined to the Active Directory domain. Possible values include: 'Yes', 'No', 'Error'
	DomainJoined DomainJoinedType `json:"domainJoined,omitempty"`
	// Credentials - Active Directory admin credentials used to join the HPC Cache to a domain.
	Credentials *CacheActiveDirectorySettingsCredentials `json:"credentials,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheActiveDirectorySettings.
func (cads CacheActiveDirectorySettings) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cads.PrimaryDNSIPAddress != nil {
		objectMap["primaryDnsIpAddress"] = cads.PrimaryDNSIPAddress
	}
	if cads.SecondaryDNSIPAddress != nil {
		objectMap["secondaryDnsIpAddress"] = cads.SecondaryDNSIPAddress
	}
	if cads.DomainName != nil {
		objectMap["domainName"] = cads.DomainName
	}
	if cads.DomainNetBiosName != nil {
		objectMap["domainNetBiosName"] = cads.DomainNetBiosName
	}
	if cads.CacheNetBiosName != nil {
		objectMap["cacheNetBiosName"] = cads.CacheNetBiosName
	}
	if cads.Credentials != nil {
		objectMap["credentials"] = cads.Credentials
	}
	return json.Marshal(objectMap)
}

// CacheActiveDirectorySettingsCredentials active Directory admin credentials used to join the HPC Cache to
// a domain.
type CacheActiveDirectorySettingsCredentials struct {
	// Username - Username of the Active Directory domain administrator. This value is stored encrypted and not returned on response.
	Username *string `json:"username,omitempty"`
	// Password - Plain text password of the Active Directory domain administrator. This value is stored encrypted and not returned on response.
	Password *string `json:"password,omitempty"`
}

// CacheDirectorySettings cache Directory Services settings.
type CacheDirectorySettings struct {
	// ActiveDirectory - Specifies settings for joining the HPC Cache to an Active Directory domain.
	ActiveDirectory *CacheActiveDirectorySettings `json:"activeDirectory,omitempty"`
	// UsernameDownload - Specifies settings for Extended Groups. Extended Groups allows users to be members of more than 16 groups.
	UsernameDownload *CacheUsernameDownloadSettings `json:"usernameDownload,omitempty"`
}

// CacheEncryptionSettings cache encryption settings.
type CacheEncryptionSettings struct {
	// KeyEncryptionKey - Specifies the location of the key encryption key in Key Vault.
	KeyEncryptionKey *KeyVaultKeyReference `json:"keyEncryptionKey,omitempty"`
}

// CacheHealth an indication of Cache health. Gives more information about health than just that related to
// provisioning.
type CacheHealth struct {
	// State - List of Cache health states. Possible values include: 'Unknown', 'Healthy', 'Degraded', 'Down', 'Transitioning', 'Stopping', 'Stopped', 'Upgrading', 'Flushing'
	State HealthStateType `json:"state,omitempty"`
	// StatusDescription - Describes explanation of state.
	StatusDescription *string `json:"statusDescription,omitempty"`
}

// CacheIdentity cache identity properties.
type CacheIdentity struct {
	// PrincipalID - READ-ONLY; The principal id of the cache.
	PrincipalID *string `json:"principalId,omitempty"`
	// TenantID - READ-ONLY; The tenant id associated with the cache.
	TenantID *string `json:"tenantId,omitempty"`
	// Type - The type of identity used for the cache. Possible values include: 'SystemAssigned', 'None'
	Type CacheIdentityType `json:"type,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheIdentity.
func (ci CacheIdentity) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ci.Type != "" {
		objectMap["type"] = ci.Type
	}
	return json.Marshal(objectMap)
}

// CacheNetworkSettings cache network settings.
type CacheNetworkSettings struct {
	// Mtu - The IPv4 maximum transmission unit configured for the subnet.
	Mtu *int32 `json:"mtu,omitempty"`
	// UtilityAddresses - READ-ONLY; Array of additional IP addresses used by this Cache.
	UtilityAddresses *[]string `json:"utilityAddresses,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheNetworkSettings.
func (cns CacheNetworkSettings) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cns.Mtu != nil {
		objectMap["mtu"] = cns.Mtu
	}
	return json.Marshal(objectMap)
}

// CacheProperties properties of the Cache.
type CacheProperties struct {
	// CacheSizeGB - The size of this Cache, in GB.
	CacheSizeGB *int32 `json:"cacheSizeGB,omitempty"`
	// Health - READ-ONLY; Health of the Cache.
	Health *CacheHealth `json:"health,omitempty"`
	// MountAddresses - READ-ONLY; Array of IP addresses that can be used by clients mounting this Cache.
	MountAddresses *[]string `json:"mountAddresses,omitempty"`
	// ProvisioningState - ARM provisioning state, see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/Addendum.md#provisioningstate-property. Possible values include: 'Succeeded', 'Failed', 'Cancelled', 'Creating', 'Deleting', 'Updating'
	ProvisioningState ProvisioningStateType `json:"provisioningState,omitempty"`
	// Subnet - Subnet used for the Cache.
	Subnet *string `json:"subnet,omitempty"`
	// UpgradeStatus - Upgrade status of the Cache.
	UpgradeStatus *CacheUpgradeStatus `json:"upgradeStatus,omitempty"`
	// NetworkSettings - Specifies network settings of the cache.
	NetworkSettings *CacheNetworkSettings `json:"networkSettings,omitempty"`
	// EncryptionSettings - Specifies encryption settings of the cache.
	EncryptionSettings *CacheEncryptionSettings `json:"encryptionSettings,omitempty"`
	// SecuritySettings - Specifies security settings of the cache.
	SecuritySettings *CacheSecuritySettings `json:"securitySettings,omitempty"`
	// DirectoryServicesSettings - Specifies Directory Services settings of the cache.
	DirectoryServicesSettings *CacheDirectorySettings `json:"directoryServicesSettings,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheProperties.
func (c CacheProperties) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if c.CacheSizeGB != nil {
		objectMap["cacheSizeGB"] = c.CacheSizeGB
	}
	if c.ProvisioningState != "" {
		objectMap["provisioningState"] = c.ProvisioningState
	}
	if c.Subnet != nil {
		objectMap["subnet"] = c.Subnet
	}
	if c.UpgradeStatus != nil {
		objectMap["upgradeStatus"] = c.UpgradeStatus
	}
	if c.NetworkSettings != nil {
		objectMap["networkSettings"] = c.NetworkSettings
	}
	if c.EncryptionSettings != nil {
		objectMap["encryptionSettings"] = c.EncryptionSettings
	}
	if c.SecuritySettings != nil {
		objectMap["securitySettings"] = c.SecuritySettings
	}
	if c.DirectoryServicesSettings != nil {
		objectMap["directoryServicesSettings"] = c.DirectoryServicesSettings
	}
	return json.Marshal(objectMap)
}

// CachesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type CachesCreateOrUpdateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (Cache, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesCreateOrUpdateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesCreateOrUpdateFuture.Result.
func (future *CachesCreateOrUpdateFuture) result(client CachesClient) (c Cache, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		c.Response.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if c.Response.Response, err = future.GetResult(sender); err == nil && c.Response.Response.StatusCode != http.StatusNoContent {
		c, err = client.CreateOrUpdateResponder(c.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "storagecache.CachesCreateOrUpdateFuture", "Result", c.Response.Response, "Failure responding to request")
		}
	}
	return
}

// CachesDebugInfoFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type CachesDebugInfoFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesDebugInfoFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesDebugInfoFuture.Result.
func (future *CachesDebugInfoFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesDebugInfoFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesDebugInfoFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CachesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type CachesDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesDeleteFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesDeleteFuture.Result.
func (future *CachesDeleteFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CacheSecuritySettings cache security settings.
type CacheSecuritySettings struct {
	// AccessPolicies - NFS access policies defined for this cache.
	AccessPolicies *[]NfsAccessPolicy `json:"accessPolicies,omitempty"`
}

// CachesFlushFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type CachesFlushFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesFlushFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesFlushFuture.Result.
func (future *CachesFlushFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesFlushFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesFlushFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CacheSku SKU for the Cache.
type CacheSku struct {
	// Name - SKU name for this Cache.
	Name *string `json:"name,omitempty"`
}

// CachesListResult result of the request to list Caches. It contains a list of Caches and a URL link to
// get the next set of results.
type CachesListResult struct {
	autorest.Response `json:"-"`
	// NextLink - URL to get the next set of Cache list results, if there are any.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - List of Caches.
	Value *[]Cache `json:"value,omitempty"`
}

// CachesListResultIterator provides access to a complete listing of Cache values.
type CachesListResultIterator struct {
	i    int
	page CachesListResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *CachesListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/CachesListResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *CachesListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter CachesListResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter CachesListResultIterator) Response() CachesListResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter CachesListResultIterator) Value() Cache {
	if !iter.page.NotDone() {
		return Cache{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the CachesListResultIterator type.
func NewCachesListResultIterator(page CachesListResultPage) CachesListResultIterator {
	return CachesListResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (clr CachesListResult) IsEmpty() bool {
	return clr.Value == nil || len(*clr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (clr CachesListResult) hasNextLink() bool {
	return clr.NextLink != nil && len(*clr.NextLink) != 0
}

// cachesListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (clr CachesListResult) cachesListResultPreparer(ctx context.Context) (*http.Request, error) {
	if !clr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(clr.NextLink)))
}

// CachesListResultPage contains a page of Cache values.
type CachesListResultPage struct {
	fn  func(context.Context, CachesListResult) (CachesListResult, error)
	clr CachesListResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *CachesListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/CachesListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.clr)
		if err != nil {
			return err
		}
		page.clr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *CachesListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page CachesListResultPage) NotDone() bool {
	return !page.clr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page CachesListResultPage) Response() CachesListResult {
	return page.clr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page CachesListResultPage) Values() []Cache {
	if page.clr.IsEmpty() {
		return nil
	}
	return *page.clr.Value
}

// Creates a new instance of the CachesListResultPage type.
func NewCachesListResultPage(cur CachesListResult, getNextPage func(context.Context, CachesListResult) (CachesListResult, error)) CachesListResultPage {
	return CachesListResultPage{
		fn:  getNextPage,
		clr: cur,
	}
}

// CachesStartFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type CachesStartFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesStartFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesStartFuture.Result.
func (future *CachesStartFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesStartFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesStartFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CachesStopFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type CachesStopFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesStopFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesStopFuture.Result.
func (future *CachesStopFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesStopFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesStopFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CachesUpgradeFirmwareFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type CachesUpgradeFirmwareFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(CachesClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *CachesUpgradeFirmwareFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for CachesUpgradeFirmwareFuture.Result.
func (future *CachesUpgradeFirmwareFuture) result(client CachesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.CachesUpgradeFirmwareFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.CachesUpgradeFirmwareFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// CacheUpgradeStatus properties describing the software upgrade state of the Cache.
type CacheUpgradeStatus struct {
	// CurrentFirmwareVersion - READ-ONLY; Version string of the firmware currently installed on this Cache.
	CurrentFirmwareVersion *string `json:"currentFirmwareVersion,omitempty"`
	// FirmwareUpdateStatus - READ-ONLY; True if there is a firmware update ready to install on this Cache. The firmware will automatically be installed after firmwareUpdateDeadline if not triggered earlier via the upgrade operation. Possible values include: 'Available', 'Unavailable'
	FirmwareUpdateStatus FirmwareStatusType `json:"firmwareUpdateStatus,omitempty"`
	// FirmwareUpdateDeadline - READ-ONLY; Time at which the pending firmware update will automatically be installed on the Cache.
	FirmwareUpdateDeadline *date.Time `json:"firmwareUpdateDeadline,omitempty"`
	// LastFirmwareUpdate - READ-ONLY; Time of the last successful firmware update.
	LastFirmwareUpdate *date.Time `json:"lastFirmwareUpdate,omitempty"`
	// PendingFirmwareVersion - READ-ONLY; When firmwareUpdateAvailable is true, this field holds the version string for the update.
	PendingFirmwareVersion *string `json:"pendingFirmwareVersion,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheUpgradeStatus.
func (cus CacheUpgradeStatus) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// CacheUsernameDownloadSettings settings for Extended Groups username and group download.
type CacheUsernameDownloadSettings struct {
	// ExtendedGroups - Whether or not Extended Groups is enabled.
	ExtendedGroups *bool `json:"extendedGroups,omitempty"`
	// UsernameSource - This setting determines how the cache gets username and group names for clients. Possible values include: 'UsernameSourceAD', 'UsernameSourceLDAP', 'UsernameSourceFile', 'UsernameSourceNone'
	UsernameSource UsernameSource `json:"usernameSource,omitempty"`
	// GroupFileURI - The URI of the file containing group information (in /etc/group file format). This field must be populated when 'usernameSource' is set to 'File'.
	GroupFileURI *string `json:"groupFileURI,omitempty"`
	// UserFileURI - The URI of the file containing user information (in /etc/passwd file format). This field must be populated when 'usernameSource' is set to 'File'.
	UserFileURI *string `json:"userFileURI,omitempty"`
	// LdapServer - The fully qualified domain name or IP address of the LDAP server to use.
	LdapServer *string `json:"ldapServer,omitempty"`
	// LdapBaseDN - The base distinguished name for the LDAP domain.
	LdapBaseDN *string `json:"ldapBaseDN,omitempty"`
	// EncryptLdapConnection - Whether or not the LDAP connection should be encrypted.
	EncryptLdapConnection *bool `json:"encryptLdapConnection,omitempty"`
	// RequireValidCertificate - Determines if the certificates must be validated by a certificate authority. When true, caCertificateURI must be provided.
	RequireValidCertificate *bool `json:"requireValidCertificate,omitempty"`
	// AutoDownloadCertificate - Determines if the certificate should be automatically downloaded. This applies to 'caCertificateURI' only if 'requireValidCertificate' is true.
	AutoDownloadCertificate *bool `json:"autoDownloadCertificate,omitempty"`
	// CaCertificateURI - The URI of the CA certificate to validate the LDAP secure connection. This field must be populated when 'requireValidCertificate' is set to true.
	CaCertificateURI *string `json:"caCertificateURI,omitempty"`
	// UsernameDownloaded - READ-ONLY; Indicates whether or not the HPC Cache has performed the username download successfully. Possible values include: 'UsernameDownloadedTypeYes', 'UsernameDownloadedTypeNo', 'UsernameDownloadedTypeError'
	UsernameDownloaded UsernameDownloadedType `json:"usernameDownloaded,omitempty"`
	// Credentials - When present, these are the credentials for the secure LDAP connection.
	Credentials *CacheUsernameDownloadSettingsCredentials `json:"credentials,omitempty"`
}

// MarshalJSON is the custom marshaler for CacheUsernameDownloadSettings.
func (cuds CacheUsernameDownloadSettings) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if cuds.ExtendedGroups != nil {
		objectMap["extendedGroups"] = cuds.ExtendedGroups
	}
	if cuds.UsernameSource != "" {
		objectMap["usernameSource"] = cuds.UsernameSource
	}
	if cuds.GroupFileURI != nil {
		objectMap["groupFileURI"] = cuds.GroupFileURI
	}
	if cuds.UserFileURI != nil {
		objectMap["userFileURI"] = cuds.UserFileURI
	}
	if cuds.LdapServer != nil {
		objectMap["ldapServer"] = cuds.LdapServer
	}
	if cuds.LdapBaseDN != nil {
		objectMap["ldapBaseDN"] = cuds.LdapBaseDN
	}
	if cuds.EncryptLdapConnection != nil {
		objectMap["encryptLdapConnection"] = cuds.EncryptLdapConnection
	}
	if cuds.RequireValidCertificate != nil {
		objectMap["requireValidCertificate"] = cuds.RequireValidCertificate
	}
	if cuds.AutoDownloadCertificate != nil {
		objectMap["autoDownloadCertificate"] = cuds.AutoDownloadCertificate
	}
	if cuds.CaCertificateURI != nil {
		objectMap["caCertificateURI"] = cuds.CaCertificateURI
	}
	if cuds.Credentials != nil {
		objectMap["credentials"] = cuds.Credentials
	}
	return json.Marshal(objectMap)
}

// CacheUsernameDownloadSettingsCredentials when present, these are the credentials for the secure LDAP
// connection.
type CacheUsernameDownloadSettingsCredentials struct {
	// BindDn - The Bind Distinguished Name identity to be used in the secure LDAP connection. This value is stored encrypted and not returned on response.
	BindDn *string `json:"bindDn,omitempty"`
	// BindPassword - The Bind password to be used in the secure LDAP connection. This value is stored encrypted and not returned on response.
	BindPassword *string `json:"bindPassword,omitempty"`
}

// ClfsTarget properties pertaining to the ClfsTarget
type ClfsTarget struct {
	// Target - Resource ID of storage container.
	Target *string `json:"target,omitempty"`
}

// ClfsTargetProperties storage container for use as a CLFS Storage Target.
type ClfsTargetProperties struct {
	// Junctions - List of Cache namespace junctions to target for namespace associations.
	Junctions *[]NamespaceJunction `json:"junctions,omitempty"`
	// ProvisioningState - ARM provisioning state, see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/Addendum.md#provisioningstate-property. Possible values include: 'Succeeded', 'Failed', 'Cancelled', 'Creating', 'Deleting', 'Updating'
	ProvisioningState ProvisioningStateType `json:"provisioningState,omitempty"`
	// Nfs3 - Properties when targetType is nfs3.
	Nfs3 *Nfs3Target `json:"nfs3,omitempty"`
	// Clfs - Properties when targetType is clfs.
	Clfs *ClfsTarget `json:"clfs,omitempty"`
	// Unknown - Properties when targetType is unknown.
	Unknown *UnknownTarget `json:"unknown,omitempty"`
	// TargetType - Possible values include: 'TargetTypeStorageTargetProperties', 'TargetTypeNfs3', 'TargetTypeClfs', 'TargetTypeUnknown'
	TargetType TargetType `json:"targetType,omitempty"`
}

// MarshalJSON is the custom marshaler for ClfsTargetProperties.
func (ctp ClfsTargetProperties) MarshalJSON() ([]byte, error) {
	ctp.TargetType = TargetTypeClfs
	objectMap := make(map[string]interface{})
	if ctp.Junctions != nil {
		objectMap["junctions"] = ctp.Junctions
	}
	if ctp.ProvisioningState != "" {
		objectMap["provisioningState"] = ctp.ProvisioningState
	}
	if ctp.Nfs3 != nil {
		objectMap["nfs3"] = ctp.Nfs3
	}
	if ctp.Clfs != nil {
		objectMap["clfs"] = ctp.Clfs
	}
	if ctp.Unknown != nil {
		objectMap["unknown"] = ctp.Unknown
	}
	if ctp.TargetType != "" {
		objectMap["targetType"] = ctp.TargetType
	}
	return json.Marshal(objectMap)
}

// AsNfs3TargetProperties is the BasicStorageTargetProperties implementation for ClfsTargetProperties.
func (ctp ClfsTargetProperties) AsNfs3TargetProperties() (*Nfs3TargetProperties, bool) {
	return nil, false
}

// AsClfsTargetProperties is the BasicStorageTargetProperties implementation for ClfsTargetProperties.
func (ctp ClfsTargetProperties) AsClfsTargetProperties() (*ClfsTargetProperties, bool) {
	return &ctp, true
}

// AsUnknownTargetProperties is the BasicStorageTargetProperties implementation for ClfsTargetProperties.
func (ctp ClfsTargetProperties) AsUnknownTargetProperties() (*UnknownTargetProperties, bool) {
	return nil, false
}

// AsStorageTargetProperties is the BasicStorageTargetProperties implementation for ClfsTargetProperties.
func (ctp ClfsTargetProperties) AsStorageTargetProperties() (*StorageTargetProperties, bool) {
	return nil, false
}

// AsBasicStorageTargetProperties is the BasicStorageTargetProperties implementation for ClfsTargetProperties.
func (ctp ClfsTargetProperties) AsBasicStorageTargetProperties() (BasicStorageTargetProperties, bool) {
	return &ctp, true
}

// CloudError an error response.
type CloudError struct {
	// Error - The body of the error.
	Error *CloudErrorBody `json:"error,omitempty"`
}

// CloudErrorBody an error response.
type CloudErrorBody struct {
	// Code - An identifier for the error. Codes are invariant and are intended to be consumed programmatically.
	Code *string `json:"code,omitempty"`
	// Details - A list of additional details about the error.
	Details *[]CloudErrorBody `json:"details,omitempty"`
	// Message - A message describing the error, intended to be suitable for display in a user interface.
	Message *string `json:"message,omitempty"`
	// Target - The target of the particular error. For example, the name of the property in error.
	Target *string `json:"target,omitempty"`
}

// ErrorResponse describes the format of Error response.
type ErrorResponse struct {
	// Code - Error code
	Code *string `json:"code,omitempty"`
	// Message - Error message indicating why the operation failed.
	Message *string `json:"message,omitempty"`
}

// KeyVaultKeyReference describes a reference to Key Vault Key.
type KeyVaultKeyReference struct {
	// KeyURL - The URL referencing a key encryption key in Key Vault.
	KeyURL *string `json:"keyUrl,omitempty"`
	// SourceVault - Describes a resource Id to source Key Vault.
	SourceVault *KeyVaultKeyReferenceSourceVault `json:"sourceVault,omitempty"`
}

// KeyVaultKeyReferenceSourceVault describes a resource Id to source Key Vault.
type KeyVaultKeyReferenceSourceVault struct {
	// ID - Resource Id.
	ID *string `json:"id,omitempty"`
}

// MetricDimension specifications of the Dimension of metrics.
type MetricDimension struct {
	// Name - Name of the dimension
	Name *string `json:"name,omitempty"`
	// DisplayName - Localized friendly display name of the dimension
	DisplayName *string `json:"displayName,omitempty"`
	// InternalName - Internal name of the dimension.
	InternalName *string `json:"internalName,omitempty"`
	// ToBeExportedForShoebox - To be exported to shoe box.
	ToBeExportedForShoebox *bool `json:"toBeExportedForShoebox,omitempty"`
}

// MetricSpecification details about operation related to metrics.
type MetricSpecification struct {
	// Name - The name of the metric.
	Name *string `json:"name,omitempty"`
	// DisplayName - Localized display name of the metric.
	DisplayName *string `json:"displayName,omitempty"`
	// DisplayDescription - The description of the metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// Unit - The unit that the metric is measured in.
	Unit *string `json:"unit,omitempty"`
	// AggregationType - The type of metric aggregation.
	AggregationType *string `json:"aggregationType,omitempty"`
	// SupportedAggregationTypes - Support metric aggregation type.
	SupportedAggregationTypes *[]MetricAggregationType `json:"supportedAggregationTypes,omitempty"`
	// MetricClass - Type of metrics.
	MetricClass *string `json:"metricClass,omitempty"`
	// Dimensions - Dimensions of the metric
	Dimensions *[]MetricDimension `json:"dimensions,omitempty"`
}

// NamespaceJunction a namespace junction.
type NamespaceJunction struct {
	// NamespacePath - Namespace path on a Cache for a Storage Target.
	NamespacePath *string `json:"namespacePath,omitempty"`
	// TargetPath - Path in Storage Target to which namespacePath points.
	TargetPath *string `json:"targetPath,omitempty"`
	// NfsExport - NFS export where targetPath exists.
	NfsExport *string `json:"nfsExport,omitempty"`
	// NfsAccessPolicy - Name of the access policy applied to this junction.
	NfsAccessPolicy *string `json:"nfsAccessPolicy,omitempty"`
}

// Nfs3Target properties pertaining to the Nfs3Target
type Nfs3Target struct {
	// Target - IP address or host name of an NFSv3 host (e.g., 10.0.44.44).
	Target *string `json:"target,omitempty"`
	// UsageModel - Identifies the usage model to be used for this Storage Target. Get choices from .../usageModels
	UsageModel *string `json:"usageModel,omitempty"`
}

// Nfs3TargetProperties an NFSv3 mount point for use as a Storage Target.
type Nfs3TargetProperties struct {
	// Junctions - List of Cache namespace junctions to target for namespace associations.
	Junctions *[]NamespaceJunction `json:"junctions,omitempty"`
	// ProvisioningState - ARM provisioning state, see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/Addendum.md#provisioningstate-property. Possible values include: 'Succeeded', 'Failed', 'Cancelled', 'Creating', 'Deleting', 'Updating'
	ProvisioningState ProvisioningStateType `json:"provisioningState,omitempty"`
	// Nfs3 - Properties when targetType is nfs3.
	Nfs3 *Nfs3Target `json:"nfs3,omitempty"`
	// Clfs - Properties when targetType is clfs.
	Clfs *ClfsTarget `json:"clfs,omitempty"`
	// Unknown - Properties when targetType is unknown.
	Unknown *UnknownTarget `json:"unknown,omitempty"`
	// TargetType - Possible values include: 'TargetTypeStorageTargetProperties', 'TargetTypeNfs3', 'TargetTypeClfs', 'TargetTypeUnknown'
	TargetType TargetType `json:"targetType,omitempty"`
}

// MarshalJSON is the custom marshaler for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) MarshalJSON() ([]byte, error) {
	n3tp.TargetType = TargetTypeNfs3
	objectMap := make(map[string]interface{})
	if n3tp.Junctions != nil {
		objectMap["junctions"] = n3tp.Junctions
	}
	if n3tp.ProvisioningState != "" {
		objectMap["provisioningState"] = n3tp.ProvisioningState
	}
	if n3tp.Nfs3 != nil {
		objectMap["nfs3"] = n3tp.Nfs3
	}
	if n3tp.Clfs != nil {
		objectMap["clfs"] = n3tp.Clfs
	}
	if n3tp.Unknown != nil {
		objectMap["unknown"] = n3tp.Unknown
	}
	if n3tp.TargetType != "" {
		objectMap["targetType"] = n3tp.TargetType
	}
	return json.Marshal(objectMap)
}

// AsNfs3TargetProperties is the BasicStorageTargetProperties implementation for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) AsNfs3TargetProperties() (*Nfs3TargetProperties, bool) {
	return &n3tp, true
}

// AsClfsTargetProperties is the BasicStorageTargetProperties implementation for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) AsClfsTargetProperties() (*ClfsTargetProperties, bool) {
	return nil, false
}

// AsUnknownTargetProperties is the BasicStorageTargetProperties implementation for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) AsUnknownTargetProperties() (*UnknownTargetProperties, bool) {
	return nil, false
}

// AsStorageTargetProperties is the BasicStorageTargetProperties implementation for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) AsStorageTargetProperties() (*StorageTargetProperties, bool) {
	return nil, false
}

// AsBasicStorageTargetProperties is the BasicStorageTargetProperties implementation for Nfs3TargetProperties.
func (n3tp Nfs3TargetProperties) AsBasicStorageTargetProperties() (BasicStorageTargetProperties, bool) {
	return &n3tp, true
}

// NfsAccessPolicy a set of rules describing access policies applied to NFSv3 clients of the cache.
type NfsAccessPolicy struct {
	// Name - Name identifying this policy. Access Policy names are not case sensitive.
	Name *string `json:"name,omitempty"`
	// AccessRules - The set of rules describing client accesses allowed under this policy.
	AccessRules *[]NfsAccessRule `json:"accessRules,omitempty"`
}

// NfsAccessRule rule to place restrictions on portions of the cache namespace being presented to clients.
type NfsAccessRule struct {
	// Scope - Scope for this rule. The scope and filter determine which clients match the rule. Possible values include: 'Default', 'Network', 'Host'
	Scope NfsAccessRuleScope `json:"scope,omitempty"`
	// Filter - Filter applied to the scope for this rule. The filter's format depends on its scope. 'default' scope matches all clients and has no filter value. 'network' scope takes a filter in CIDR format (for example, 10.99.1.0/24). 'host' takes an IP address or fully qualified domain name as filter. If a client does not match any filter rule and there is no default rule, access is denied.
	Filter *string `json:"filter,omitempty"`
	// Access - Access allowed by this rule. Possible values include: 'NfsAccessRuleAccessNo', 'NfsAccessRuleAccessRo', 'NfsAccessRuleAccessRw'
	Access NfsAccessRuleAccess `json:"access,omitempty"`
	// Suid - Allow SUID semantics.
	Suid *bool `json:"suid,omitempty"`
	// SubmountAccess - For the default policy, allow access to subdirectories under the root export. If this is set to no, clients can only mount the path '/'. If set to yes, clients can mount a deeper path, like '/a/b'.
	SubmountAccess *bool `json:"submountAccess,omitempty"`
	// RootSquash - Map root accesses to anonymousUID and anonymousGID.
	RootSquash *bool `json:"rootSquash,omitempty"`
	// AnonymousUID - UID value that replaces 0 when rootSquash is true.
	AnonymousUID *string `json:"anonymousUID,omitempty"`
	// AnonymousGID - GID value that replaces 0 when rootSquash is true.
	AnonymousGID *string `json:"anonymousGID,omitempty"`
}

// ResourceSku a resource SKU.
type ResourceSku struct {
	// ResourceType - READ-ONLY; The type of resource the SKU applies to.
	ResourceType *string `json:"resourceType,omitempty"`
	// Capabilities - A list of capabilities of this SKU, such as throughput or ops/sec.
	Capabilities *[]ResourceSkuCapabilities `json:"capabilities,omitempty"`
	// Locations - READ-ONLY; The set of locations where the SKU is available. This is the supported and registered Azure Geo Regions (e.g., West US, East US, Southeast Asia, etc.).
	Locations *[]string `json:"locations,omitempty"`
	// LocationInfo - The set of locations where the SKU is available.
	LocationInfo *[]ResourceSkuLocationInfo `json:"locationInfo,omitempty"`
	// Name - The name of this SKU.
	Name *string `json:"name,omitempty"`
	// Restrictions - The restrictions preventing this SKU from being used. This is empty if there are no restrictions.
	Restrictions *[]Restriction `json:"restrictions,omitempty"`
}

// MarshalJSON is the custom marshaler for ResourceSku.
func (rs ResourceSku) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rs.Capabilities != nil {
		objectMap["capabilities"] = rs.Capabilities
	}
	if rs.LocationInfo != nil {
		objectMap["locationInfo"] = rs.LocationInfo
	}
	if rs.Name != nil {
		objectMap["name"] = rs.Name
	}
	if rs.Restrictions != nil {
		objectMap["restrictions"] = rs.Restrictions
	}
	return json.Marshal(objectMap)
}

// ResourceSkuCapabilities a resource SKU capability.
type ResourceSkuCapabilities struct {
	// Name - Name of a capability, such as ops/sec.
	Name *string `json:"name,omitempty"`
	// Value - Quantity, if the capability is measured by quantity.
	Value *string `json:"value,omitempty"`
}

// ResourceSkuLocationInfo resource SKU location information.
type ResourceSkuLocationInfo struct {
	// Location - Location where this SKU is available.
	Location *string `json:"location,omitempty"`
	// Zones - Zones if any.
	Zones *[]string `json:"zones,omitempty"`
}

// ResourceSkusResult the response from the List Cache SKUs operation.
type ResourceSkusResult struct {
	autorest.Response `json:"-"`
	// NextLink - The URI to fetch the next page of Cache SKUs.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - READ-ONLY; The list of SKUs available for the subscription.
	Value *[]ResourceSku `json:"value,omitempty"`
}

// MarshalJSON is the custom marshaler for ResourceSkusResult.
func (rsr ResourceSkusResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rsr.NextLink != nil {
		objectMap["nextLink"] = rsr.NextLink
	}
	return json.Marshal(objectMap)
}

// ResourceSkusResultIterator provides access to a complete listing of ResourceSku values.
type ResourceSkusResultIterator struct {
	i    int
	page ResourceSkusResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *ResourceSkusResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ResourceSkusResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *ResourceSkusResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ResourceSkusResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter ResourceSkusResultIterator) Response() ResourceSkusResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter ResourceSkusResultIterator) Value() ResourceSku {
	if !iter.page.NotDone() {
		return ResourceSku{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the ResourceSkusResultIterator type.
func NewResourceSkusResultIterator(page ResourceSkusResultPage) ResourceSkusResultIterator {
	return ResourceSkusResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (rsr ResourceSkusResult) IsEmpty() bool {
	return rsr.Value == nil || len(*rsr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (rsr ResourceSkusResult) hasNextLink() bool {
	return rsr.NextLink != nil && len(*rsr.NextLink) != 0
}

// resourceSkusResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rsr ResourceSkusResult) resourceSkusResultPreparer(ctx context.Context) (*http.Request, error) {
	if !rsr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rsr.NextLink)))
}

// ResourceSkusResultPage contains a page of ResourceSku values.
type ResourceSkusResultPage struct {
	fn  func(context.Context, ResourceSkusResult) (ResourceSkusResult, error)
	rsr ResourceSkusResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *ResourceSkusResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ResourceSkusResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.rsr)
		if err != nil {
			return err
		}
		page.rsr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *ResourceSkusResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page ResourceSkusResultPage) NotDone() bool {
	return !page.rsr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page ResourceSkusResultPage) Response() ResourceSkusResult {
	return page.rsr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page ResourceSkusResultPage) Values() []ResourceSku {
	if page.rsr.IsEmpty() {
		return nil
	}
	return *page.rsr.Value
}

// Creates a new instance of the ResourceSkusResultPage type.
func NewResourceSkusResultPage(cur ResourceSkusResult, getNextPage func(context.Context, ResourceSkusResult) (ResourceSkusResult, error)) ResourceSkusResultPage {
	return ResourceSkusResultPage{
		fn:  getNextPage,
		rsr: cur,
	}
}

// Restriction the restrictions preventing this SKU from being used.
type Restriction struct {
	// Type - READ-ONLY; The type of restrictions. In this version, the only possible value for this is location.
	Type *string `json:"type,omitempty"`
	// Values - READ-ONLY; The value of restrictions. If the restriction type is set to location, then this would be the different locations where the SKU is restricted.
	Values *[]string `json:"values,omitempty"`
	// ReasonCode - The reason for the restriction. As of now this can be "QuotaId" or "NotAvailableForSubscription". "QuotaId" is set when the SKU has requiredQuotas parameter as the subscription does not belong to that quota. "NotAvailableForSubscription" is related to capacity at the datacenter. Possible values include: 'QuotaID', 'NotAvailableForSubscription'
	ReasonCode ReasonCode `json:"reasonCode,omitempty"`
}

// MarshalJSON is the custom marshaler for Restriction.
func (r Restriction) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if r.ReasonCode != "" {
		objectMap["reasonCode"] = r.ReasonCode
	}
	return json.Marshal(objectMap)
}

// StorageTarget type of the Storage Target.
type StorageTarget struct {
	autorest.Response `json:"-"`
	// BasicStorageTargetProperties - StorageTarget properties
	BasicStorageTargetProperties `json:"properties,omitempty"`
	// Name - READ-ONLY; Name of the Storage Target.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; Resource ID of the Storage Target.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; Type of the Storage Target; Microsoft.StorageCache/Cache/StorageTarget
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; Region name string.
	Location *string `json:"location,omitempty"`
	// SystemData - READ-ONLY; The system meta data relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
}

// MarshalJSON is the custom marshaler for StorageTarget.
func (st StorageTarget) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	objectMap["properties"] = st.BasicStorageTargetProperties
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for StorageTarget struct.
func (st *StorageTarget) UnmarshalJSON(body []byte) error {
	var m map[string]*json.RawMessage
	err := json.Unmarshal(body, &m)
	if err != nil {
		return err
	}
	for k, v := range m {
		switch k {
		case "properties":
			if v != nil {
				basicStorageTargetProperties, err := unmarshalBasicStorageTargetProperties(*v)
				if err != nil {
					return err
				}
				st.BasicStorageTargetProperties = basicStorageTargetProperties
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				st.Name = &name
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				st.ID = &ID
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				st.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				st.Location = &location
			}
		case "systemData":
			if v != nil {
				var systemData SystemData
				err = json.Unmarshal(*v, &systemData)
				if err != nil {
					return err
				}
				st.SystemData = &systemData
			}
		}
	}

	return nil
}

// BasicStorageTargetProperties properties of the Storage Target.
type BasicStorageTargetProperties interface {
	AsNfs3TargetProperties() (*Nfs3TargetProperties, bool)
	AsClfsTargetProperties() (*ClfsTargetProperties, bool)
	AsUnknownTargetProperties() (*UnknownTargetProperties, bool)
	AsStorageTargetProperties() (*StorageTargetProperties, bool)
}

// StorageTargetProperties properties of the Storage Target.
type StorageTargetProperties struct {
	// Junctions - List of Cache namespace junctions to target for namespace associations.
	Junctions *[]NamespaceJunction `json:"junctions,omitempty"`
	// ProvisioningState - ARM provisioning state, see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/Addendum.md#provisioningstate-property. Possible values include: 'Succeeded', 'Failed', 'Cancelled', 'Creating', 'Deleting', 'Updating'
	ProvisioningState ProvisioningStateType `json:"provisioningState,omitempty"`
	// Nfs3 - Properties when targetType is nfs3.
	Nfs3 *Nfs3Target `json:"nfs3,omitempty"`
	// Clfs - Properties when targetType is clfs.
	Clfs *ClfsTarget `json:"clfs,omitempty"`
	// Unknown - Properties when targetType is unknown.
	Unknown *UnknownTarget `json:"unknown,omitempty"`
	// TargetType - Possible values include: 'TargetTypeStorageTargetProperties', 'TargetTypeNfs3', 'TargetTypeClfs', 'TargetTypeUnknown'
	TargetType TargetType `json:"targetType,omitempty"`
}

func unmarshalBasicStorageTargetProperties(body []byte) (BasicStorageTargetProperties, error) {
	var m map[string]interface{}
	err := json.Unmarshal(body, &m)
	if err != nil {
		return nil, err
	}

	switch m["targetType"] {
	case string(TargetTypeNfs3):
		var n3tp Nfs3TargetProperties
		err := json.Unmarshal(body, &n3tp)
		return n3tp, err
	case string(TargetTypeClfs):
		var ctp ClfsTargetProperties
		err := json.Unmarshal(body, &ctp)
		return ctp, err
	case string(TargetTypeUnknown):
		var utp UnknownTargetProperties
		err := json.Unmarshal(body, &utp)
		return utp, err
	default:
		var stp StorageTargetProperties
		err := json.Unmarshal(body, &stp)
		return stp, err
	}
}
func unmarshalBasicStorageTargetPropertiesArray(body []byte) ([]BasicStorageTargetProperties, error) {
	var rawMessages []*json.RawMessage
	err := json.Unmarshal(body, &rawMessages)
	if err != nil {
		return nil, err
	}

	stpArray := make([]BasicStorageTargetProperties, len(rawMessages))

	for index, rawMessage := range rawMessages {
		stp, err := unmarshalBasicStorageTargetProperties(*rawMessage)
		if err != nil {
			return nil, err
		}
		stpArray[index] = stp
	}
	return stpArray, nil
}

// MarshalJSON is the custom marshaler for StorageTargetProperties.
func (stp StorageTargetProperties) MarshalJSON() ([]byte, error) {
	stp.TargetType = TargetTypeStorageTargetProperties
	objectMap := make(map[string]interface{})
	if stp.Junctions != nil {
		objectMap["junctions"] = stp.Junctions
	}
	if stp.ProvisioningState != "" {
		objectMap["provisioningState"] = stp.ProvisioningState
	}
	if stp.Nfs3 != nil {
		objectMap["nfs3"] = stp.Nfs3
	}
	if stp.Clfs != nil {
		objectMap["clfs"] = stp.Clfs
	}
	if stp.Unknown != nil {
		objectMap["unknown"] = stp.Unknown
	}
	if stp.TargetType != "" {
		objectMap["targetType"] = stp.TargetType
	}
	return json.Marshal(objectMap)
}

// AsNfs3TargetProperties is the BasicStorageTargetProperties implementation for StorageTargetProperties.
func (stp StorageTargetProperties) AsNfs3TargetProperties() (*Nfs3TargetProperties, bool) {
	return nil, false
}

// AsClfsTargetProperties is the BasicStorageTargetProperties implementation for StorageTargetProperties.
func (stp StorageTargetProperties) AsClfsTargetProperties() (*ClfsTargetProperties, bool) {
	return nil, false
}

// AsUnknownTargetProperties is the BasicStorageTargetProperties implementation for StorageTargetProperties.
func (stp StorageTargetProperties) AsUnknownTargetProperties() (*UnknownTargetProperties, bool) {
	return nil, false
}

// AsStorageTargetProperties is the BasicStorageTargetProperties implementation for StorageTargetProperties.
func (stp StorageTargetProperties) AsStorageTargetProperties() (*StorageTargetProperties, bool) {
	return &stp, true
}

// AsBasicStorageTargetProperties is the BasicStorageTargetProperties implementation for StorageTargetProperties.
func (stp StorageTargetProperties) AsBasicStorageTargetProperties() (BasicStorageTargetProperties, bool) {
	return &stp, true
}

// StorageTargetResource resource used by a Cache.
type StorageTargetResource struct {
	// Name - READ-ONLY; Name of the Storage Target.
	Name *string `json:"name,omitempty"`
	// ID - READ-ONLY; Resource ID of the Storage Target.
	ID *string `json:"id,omitempty"`
	// Type - READ-ONLY; Type of the Storage Target; Microsoft.StorageCache/Cache/StorageTarget
	Type *string `json:"type,omitempty"`
	// Location - READ-ONLY; Region name string.
	Location *string `json:"location,omitempty"`
	// SystemData - READ-ONLY; The system meta data relating to this resource.
	SystemData *SystemData `json:"systemData,omitempty"`
}

// MarshalJSON is the custom marshaler for StorageTargetResource.
func (str StorageTargetResource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	return json.Marshal(objectMap)
}

// StorageTargetsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type StorageTargetsCreateOrUpdateFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(StorageTargetsClient) (StorageTarget, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *StorageTargetsCreateOrUpdateFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for StorageTargetsCreateOrUpdateFuture.Result.
func (future *StorageTargetsCreateOrUpdateFuture) result(client StorageTargetsClient) (st StorageTarget, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.StorageTargetsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		st.Response.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.StorageTargetsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if st.Response.Response, err = future.GetResult(sender); err == nil && st.Response.Response.StatusCode != http.StatusNoContent {
		st, err = client.CreateOrUpdateResponder(st.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "storagecache.StorageTargetsCreateOrUpdateFuture", "Result", st.Response.Response, "Failure responding to request")
		}
	}
	return
}

// StorageTargetsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type StorageTargetsDeleteFuture struct {
	azure.FutureAPI
	// Result returns the result of the asynchronous operation.
	// If the operation has not completed it will return an error.
	Result func(StorageTargetsClient) (autorest.Response, error)
}

// UnmarshalJSON is the custom unmarshaller for CreateFuture.
func (future *StorageTargetsDeleteFuture) UnmarshalJSON(body []byte) error {
	var azFuture azure.Future
	if err := json.Unmarshal(body, &azFuture); err != nil {
		return err
	}
	future.FutureAPI = &azFuture
	future.Result = future.result
	return nil
}

// result is the default implementation for StorageTargetsDeleteFuture.Result.
func (future *StorageTargetsDeleteFuture) result(client StorageTargetsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.DoneWithContext(context.Background(), client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "storagecache.StorageTargetsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		ar.Response = future.Response()
		err = azure.NewAsyncOpIncompleteError("storagecache.StorageTargetsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// StorageTargetsResult a list of Storage Targets.
type StorageTargetsResult struct {
	autorest.Response `json:"-"`
	// NextLink - The URI to fetch the next page of Storage Targets.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - The list of Storage Targets defined for the Cache.
	Value *[]StorageTarget `json:"value,omitempty"`
}

// StorageTargetsResultIterator provides access to a complete listing of StorageTarget values.
type StorageTargetsResultIterator struct {
	i    int
	page StorageTargetsResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *StorageTargetsResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/StorageTargetsResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *StorageTargetsResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter StorageTargetsResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter StorageTargetsResultIterator) Response() StorageTargetsResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter StorageTargetsResultIterator) Value() StorageTarget {
	if !iter.page.NotDone() {
		return StorageTarget{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the StorageTargetsResultIterator type.
func NewStorageTargetsResultIterator(page StorageTargetsResultPage) StorageTargetsResultIterator {
	return StorageTargetsResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (str StorageTargetsResult) IsEmpty() bool {
	return str.Value == nil || len(*str.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (str StorageTargetsResult) hasNextLink() bool {
	return str.NextLink != nil && len(*str.NextLink) != 0
}

// storageTargetsResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (str StorageTargetsResult) storageTargetsResultPreparer(ctx context.Context) (*http.Request, error) {
	if !str.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(str.NextLink)))
}

// StorageTargetsResultPage contains a page of StorageTarget values.
type StorageTargetsResultPage struct {
	fn  func(context.Context, StorageTargetsResult) (StorageTargetsResult, error)
	str StorageTargetsResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *StorageTargetsResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/StorageTargetsResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.str)
		if err != nil {
			return err
		}
		page.str = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *StorageTargetsResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page StorageTargetsResultPage) NotDone() bool {
	return !page.str.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page StorageTargetsResultPage) Response() StorageTargetsResult {
	return page.str
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page StorageTargetsResultPage) Values() []StorageTarget {
	if page.str.IsEmpty() {
		return nil
	}
	return *page.str.Value
}

// Creates a new instance of the StorageTargetsResultPage type.
func NewStorageTargetsResultPage(cur StorageTargetsResult, getNextPage func(context.Context, StorageTargetsResult) (StorageTargetsResult, error)) StorageTargetsResultPage {
	return StorageTargetsResultPage{
		fn:  getNextPage,
		str: cur,
	}
}

// SystemData metadata pertaining to creation and last modification of the resource.
type SystemData struct {
	// CreatedBy - The identity that created the resource.
	CreatedBy *string `json:"createdBy,omitempty"`
	// CreatedByType - The type of identity that created the resource. Possible values include: 'User', 'Application', 'ManagedIdentity', 'Key'
	CreatedByType CreatedByType `json:"createdByType,omitempty"`
	// CreatedAt - The timestamp of resource creation (UTC).
	CreatedAt *date.Time `json:"createdAt,omitempty"`
	// LastModifiedBy - The identity that last modified the resource.
	LastModifiedBy *string `json:"lastModifiedBy,omitempty"`
	// LastModifiedByType - The type of identity that last modified the resource. Possible values include: 'User', 'Application', 'ManagedIdentity', 'Key'
	LastModifiedByType CreatedByType `json:"lastModifiedByType,omitempty"`
	// LastModifiedAt - The timestamp of resource last modification (UTC)
	LastModifiedAt *date.Time `json:"lastModifiedAt,omitempty"`
}

// UnknownTarget properties pertaining to the UnknownTarget
type UnknownTarget struct {
	// UnknownMap - Dictionary of string->string pairs containing information about the Storage Target.
	UnknownMap map[string]*string `json:"unknownMap"`
}

// MarshalJSON is the custom marshaler for UnknownTarget.
func (ut UnknownTarget) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ut.UnknownMap != nil {
		objectMap["unknownMap"] = ut.UnknownMap
	}
	return json.Marshal(objectMap)
}

// UnknownTargetProperties storage container for use as an Unknown Storage Target.
type UnknownTargetProperties struct {
	// Junctions - List of Cache namespace junctions to target for namespace associations.
	Junctions *[]NamespaceJunction `json:"junctions,omitempty"`
	// ProvisioningState - ARM provisioning state, see https://github.com/Azure/azure-resource-manager-rpc/blob/master/v1.0/Addendum.md#provisioningstate-property. Possible values include: 'Succeeded', 'Failed', 'Cancelled', 'Creating', 'Deleting', 'Updating'
	ProvisioningState ProvisioningStateType `json:"provisioningState,omitempty"`
	// Nfs3 - Properties when targetType is nfs3.
	Nfs3 *Nfs3Target `json:"nfs3,omitempty"`
	// Clfs - Properties when targetType is clfs.
	Clfs *ClfsTarget `json:"clfs,omitempty"`
	// Unknown - Properties when targetType is unknown.
	Unknown *UnknownTarget `json:"unknown,omitempty"`
	// TargetType - Possible values include: 'TargetTypeStorageTargetProperties', 'TargetTypeNfs3', 'TargetTypeClfs', 'TargetTypeUnknown'
	TargetType TargetType `json:"targetType,omitempty"`
}

// MarshalJSON is the custom marshaler for UnknownTargetProperties.
func (utp UnknownTargetProperties) MarshalJSON() ([]byte, error) {
	utp.TargetType = TargetTypeUnknown
	objectMap := make(map[string]interface{})
	if utp.Junctions != nil {
		objectMap["junctions"] = utp.Junctions
	}
	if utp.ProvisioningState != "" {
		objectMap["provisioningState"] = utp.ProvisioningState
	}
	if utp.Nfs3 != nil {
		objectMap["nfs3"] = utp.Nfs3
	}
	if utp.Clfs != nil {
		objectMap["clfs"] = utp.Clfs
	}
	if utp.Unknown != nil {
		objectMap["unknown"] = utp.Unknown
	}
	if utp.TargetType != "" {
		objectMap["targetType"] = utp.TargetType
	}
	return json.Marshal(objectMap)
}

// AsNfs3TargetProperties is the BasicStorageTargetProperties implementation for UnknownTargetProperties.
func (utp UnknownTargetProperties) AsNfs3TargetProperties() (*Nfs3TargetProperties, bool) {
	return nil, false
}

// AsClfsTargetProperties is the BasicStorageTargetProperties implementation for UnknownTargetProperties.
func (utp UnknownTargetProperties) AsClfsTargetProperties() (*ClfsTargetProperties, bool) {
	return nil, false
}

// AsUnknownTargetProperties is the BasicStorageTargetProperties implementation for UnknownTargetProperties.
func (utp UnknownTargetProperties) AsUnknownTargetProperties() (*UnknownTargetProperties, bool) {
	return &utp, true
}

// AsStorageTargetProperties is the BasicStorageTargetProperties implementation for UnknownTargetProperties.
func (utp UnknownTargetProperties) AsStorageTargetProperties() (*StorageTargetProperties, bool) {
	return nil, false
}

// AsBasicStorageTargetProperties is the BasicStorageTargetProperties implementation for UnknownTargetProperties.
func (utp UnknownTargetProperties) AsBasicStorageTargetProperties() (BasicStorageTargetProperties, bool) {
	return &utp, true
}

// UsageModel a usage model.
type UsageModel struct {
	// Display - Localized information describing this usage model.
	Display *UsageModelDisplay `json:"display,omitempty"`
	// ModelName - Non-localized keyword name for this usage model.
	ModelName *string `json:"modelName,omitempty"`
	// TargetType - The type of Storage Target to which this model is applicable (only nfs3 as of this version).
	TargetType *string `json:"targetType,omitempty"`
}

// UsageModelDisplay localized information describing this usage model.
type UsageModelDisplay struct {
	// Description - String to display for this usage model.
	Description *string `json:"description,omitempty"`
}

// UsageModelsResult a list of Cache usage models.
type UsageModelsResult struct {
	autorest.Response `json:"-"`
	// NextLink - The URI to fetch the next page of Cache usage models.
	NextLink *string `json:"nextLink,omitempty"`
	// Value - The list of usage models available for the subscription.
	Value *[]UsageModel `json:"value,omitempty"`
}

// UsageModelsResultIterator provides access to a complete listing of UsageModel values.
type UsageModelsResultIterator struct {
	i    int
	page UsageModelsResultPage
}

// NextWithContext advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
func (iter *UsageModelsResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/UsageModelsResultIterator.NextWithContext")
		defer func() {
			sc := -1
			if iter.Response().Response.Response != nil {
				sc = iter.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	iter.i++
	if iter.i < len(iter.page.Values()) {
		return nil
	}
	err = iter.page.NextWithContext(ctx)
	if err != nil {
		iter.i--
		return err
	}
	iter.i = 0
	return nil
}

// Next advances to the next value.  If there was an error making
// the request the iterator does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (iter *UsageModelsResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter UsageModelsResultIterator) NotDone() bool {
	return iter.page.NotDone() && iter.i < len(iter.page.Values())
}

// Response returns the raw server response from the last page request.
func (iter UsageModelsResultIterator) Response() UsageModelsResult {
	return iter.page.Response()
}

// Value returns the current value or a zero-initialized value if the
// iterator has advanced beyond the end of the collection.
func (iter UsageModelsResultIterator) Value() UsageModel {
	if !iter.page.NotDone() {
		return UsageModel{}
	}
	return iter.page.Values()[iter.i]
}

// Creates a new instance of the UsageModelsResultIterator type.
func NewUsageModelsResultIterator(page UsageModelsResultPage) UsageModelsResultIterator {
	return UsageModelsResultIterator{page: page}
}

// IsEmpty returns true if the ListResult contains no values.
func (umr UsageModelsResult) IsEmpty() bool {
	return umr.Value == nil || len(*umr.Value) == 0
}

// hasNextLink returns true if the NextLink is not empty.
func (umr UsageModelsResult) hasNextLink() bool {
	return umr.NextLink != nil && len(*umr.NextLink) != 0
}

// usageModelsResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (umr UsageModelsResult) usageModelsResultPreparer(ctx context.Context) (*http.Request, error) {
	if !umr.hasNextLink() {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(umr.NextLink)))
}

// UsageModelsResultPage contains a page of UsageModel values.
type UsageModelsResultPage struct {
	fn  func(context.Context, UsageModelsResult) (UsageModelsResult, error)
	umr UsageModelsResult
}

// NextWithContext advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
func (page *UsageModelsResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/UsageModelsResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	for {
		next, err := page.fn(ctx, page.umr)
		if err != nil {
			return err
		}
		page.umr = next
		if !next.hasNextLink() || !next.IsEmpty() {
			break
		}
	}
	return nil
}

// Next advances to the next page of values.  If there was an error making
// the request the page does not advance and the error is returned.
// Deprecated: Use NextWithContext() instead.
func (page *UsageModelsResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

// NotDone returns true if the page enumeration should be started or is not yet complete.
func (page UsageModelsResultPage) NotDone() bool {
	return !page.umr.IsEmpty()
}

// Response returns the raw server response from the last page request.
func (page UsageModelsResultPage) Response() UsageModelsResult {
	return page.umr
}

// Values returns the slice of values for the current page or nil if there are no values.
func (page UsageModelsResultPage) Values() []UsageModel {
	if page.umr.IsEmpty() {
		return nil
	}
	return *page.umr.Value
}

// Creates a new instance of the UsageModelsResultPage type.
func NewUsageModelsResultPage(cur UsageModelsResult, getNextPage func(context.Context, UsageModelsResult) (UsageModelsResult, error)) UsageModelsResultPage {
	return UsageModelsResultPage{
		fn:  getNextPage,
		umr: cur,
	}
}
