package network

// Copyright (c) Microsoft and contributors.  All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//
// See the License for the specific language governing permissions and
// limitations under the License.
//
// 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/network/mgmt/2017-09-01/network"

// Access enumerates the values for access.
type Access string

const (
	// Allow ...
	Allow Access = "Allow"
	// Deny ...
	Deny Access = "Deny"
)

// PossibleAccessValues returns an array of possible values for the Access const type.
func PossibleAccessValues() []Access {
	return []Access{Allow, Deny}
}

// ApplicationGatewayBackendHealthServerHealth enumerates the values for application gateway backend health
// server health.
type ApplicationGatewayBackendHealthServerHealth string

const (
	// Down ...
	Down ApplicationGatewayBackendHealthServerHealth = "Down"
	// Draining ...
	Draining ApplicationGatewayBackendHealthServerHealth = "Draining"
	// Partial ...
	Partial ApplicationGatewayBackendHealthServerHealth = "Partial"
	// Unknown ...
	Unknown ApplicationGatewayBackendHealthServerHealth = "Unknown"
	// Up ...
	Up ApplicationGatewayBackendHealthServerHealth = "Up"
)

// PossibleApplicationGatewayBackendHealthServerHealthValues returns an array of possible values for the ApplicationGatewayBackendHealthServerHealth const type.
func PossibleApplicationGatewayBackendHealthServerHealthValues() []ApplicationGatewayBackendHealthServerHealth {
	return []ApplicationGatewayBackendHealthServerHealth{Down, Draining, Partial, Unknown, Up}
}

// ApplicationGatewayCookieBasedAffinity enumerates the values for application gateway cookie based affinity.
type ApplicationGatewayCookieBasedAffinity string

const (
	// Disabled ...
	Disabled ApplicationGatewayCookieBasedAffinity = "Disabled"
	// Enabled ...
	Enabled ApplicationGatewayCookieBasedAffinity = "Enabled"
)

// PossibleApplicationGatewayCookieBasedAffinityValues returns an array of possible values for the ApplicationGatewayCookieBasedAffinity const type.
func PossibleApplicationGatewayCookieBasedAffinityValues() []ApplicationGatewayCookieBasedAffinity {
	return []ApplicationGatewayCookieBasedAffinity{Disabled, Enabled}
}

// ApplicationGatewayFirewallMode enumerates the values for application gateway firewall mode.
type ApplicationGatewayFirewallMode string

const (
	// Detection ...
	Detection ApplicationGatewayFirewallMode = "Detection"
	// Prevention ...
	Prevention ApplicationGatewayFirewallMode = "Prevention"
)

// PossibleApplicationGatewayFirewallModeValues returns an array of possible values for the ApplicationGatewayFirewallMode const type.
func PossibleApplicationGatewayFirewallModeValues() []ApplicationGatewayFirewallMode {
	return []ApplicationGatewayFirewallMode{Detection, Prevention}
}

// ApplicationGatewayOperationalState enumerates the values for application gateway operational state.
type ApplicationGatewayOperationalState string

const (
	// Running ...
	Running ApplicationGatewayOperationalState = "Running"
	// Starting ...
	Starting ApplicationGatewayOperationalState = "Starting"
	// Stopped ...
	Stopped ApplicationGatewayOperationalState = "Stopped"
	// Stopping ...
	Stopping ApplicationGatewayOperationalState = "Stopping"
)

// PossibleApplicationGatewayOperationalStateValues returns an array of possible values for the ApplicationGatewayOperationalState const type.
func PossibleApplicationGatewayOperationalStateValues() []ApplicationGatewayOperationalState {
	return []ApplicationGatewayOperationalState{Running, Starting, Stopped, Stopping}
}

// ApplicationGatewayProtocol enumerates the values for application gateway protocol.
type ApplicationGatewayProtocol string

const (
	// HTTP ...
	HTTP ApplicationGatewayProtocol = "Http"
	// HTTPS ...
	HTTPS ApplicationGatewayProtocol = "Https"
)

// PossibleApplicationGatewayProtocolValues returns an array of possible values for the ApplicationGatewayProtocol const type.
func PossibleApplicationGatewayProtocolValues() []ApplicationGatewayProtocol {
	return []ApplicationGatewayProtocol{HTTP, HTTPS}
}

// ApplicationGatewayRedirectType enumerates the values for application gateway redirect type.
type ApplicationGatewayRedirectType string

const (
	// Found ...
	Found ApplicationGatewayRedirectType = "Found"
	// Permanent ...
	Permanent ApplicationGatewayRedirectType = "Permanent"
	// SeeOther ...
	SeeOther ApplicationGatewayRedirectType = "SeeOther"
	// Temporary ...
	Temporary ApplicationGatewayRedirectType = "Temporary"
)

// PossibleApplicationGatewayRedirectTypeValues returns an array of possible values for the ApplicationGatewayRedirectType const type.
func PossibleApplicationGatewayRedirectTypeValues() []ApplicationGatewayRedirectType {
	return []ApplicationGatewayRedirectType{Found, Permanent, SeeOther, Temporary}
}

// ApplicationGatewayRequestRoutingRuleType enumerates the values for application gateway request routing rule
// type.
type ApplicationGatewayRequestRoutingRuleType string

const (
	// Basic ...
	Basic ApplicationGatewayRequestRoutingRuleType = "Basic"
	// PathBasedRouting ...
	PathBasedRouting ApplicationGatewayRequestRoutingRuleType = "PathBasedRouting"
)

// PossibleApplicationGatewayRequestRoutingRuleTypeValues returns an array of possible values for the ApplicationGatewayRequestRoutingRuleType const type.
func PossibleApplicationGatewayRequestRoutingRuleTypeValues() []ApplicationGatewayRequestRoutingRuleType {
	return []ApplicationGatewayRequestRoutingRuleType{Basic, PathBasedRouting}
}

// ApplicationGatewaySkuName enumerates the values for application gateway sku name.
type ApplicationGatewaySkuName string

const (
	// StandardLarge ...
	StandardLarge ApplicationGatewaySkuName = "Standard_Large"
	// StandardMedium ...
	StandardMedium ApplicationGatewaySkuName = "Standard_Medium"
	// StandardSmall ...
	StandardSmall ApplicationGatewaySkuName = "Standard_Small"
	// WAFLarge ...
	WAFLarge ApplicationGatewaySkuName = "WAF_Large"
	// WAFMedium ...
	WAFMedium ApplicationGatewaySkuName = "WAF_Medium"
)

// PossibleApplicationGatewaySkuNameValues returns an array of possible values for the ApplicationGatewaySkuName const type.
func PossibleApplicationGatewaySkuNameValues() []ApplicationGatewaySkuName {
	return []ApplicationGatewaySkuName{StandardLarge, StandardMedium, StandardSmall, WAFLarge, WAFMedium}
}

// ApplicationGatewaySslCipherSuite enumerates the values for application gateway ssl cipher suite.
type ApplicationGatewaySslCipherSuite string

const (
	// TLSDHEDSSWITHAES128CBCSHA ...
	TLSDHEDSSWITHAES128CBCSHA ApplicationGatewaySslCipherSuite = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA"
	// TLSDHEDSSWITHAES128CBCSHA256 ...
	TLSDHEDSSWITHAES128CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256"
	// TLSDHEDSSWITHAES256CBCSHA ...
	TLSDHEDSSWITHAES256CBCSHA ApplicationGatewaySslCipherSuite = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA"
	// TLSDHEDSSWITHAES256CBCSHA256 ...
	TLSDHEDSSWITHAES256CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256"
	// TLSDHERSAWITHAES128CBCSHA ...
	TLSDHERSAWITHAES128CBCSHA ApplicationGatewaySslCipherSuite = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA"
	// TLSDHERSAWITHAES128GCMSHA256 ...
	TLSDHERSAWITHAES128GCMSHA256 ApplicationGatewaySslCipherSuite = "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"
	// TLSDHERSAWITHAES256CBCSHA ...
	TLSDHERSAWITHAES256CBCSHA ApplicationGatewaySslCipherSuite = "TLS_DHE_RSA_WITH_AES_256_CBC_SHA"
	// TLSDHERSAWITHAES256GCMSHA384 ...
	TLSDHERSAWITHAES256GCMSHA384 ApplicationGatewaySslCipherSuite = "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"
	// TLSECDHEECDSAWITHAES128CBCSHA ...
	TLSECDHEECDSAWITHAES128CBCSHA ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"
	// TLSECDHEECDSAWITHAES128CBCSHA256 ...
	TLSECDHEECDSAWITHAES128CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"
	// TLSECDHEECDSAWITHAES128GCMSHA256 ...
	TLSECDHEECDSAWITHAES128GCMSHA256 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
	// TLSECDHEECDSAWITHAES256CBCSHA ...
	TLSECDHEECDSAWITHAES256CBCSHA ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"
	// TLSECDHEECDSAWITHAES256CBCSHA384 ...
	TLSECDHEECDSAWITHAES256CBCSHA384 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"
	// TLSECDHEECDSAWITHAES256GCMSHA384 ...
	TLSECDHEECDSAWITHAES256GCMSHA384 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
	// TLSECDHERSAWITHAES128CBCSHA ...
	TLSECDHERSAWITHAES128CBCSHA ApplicationGatewaySslCipherSuite = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"
	// TLSECDHERSAWITHAES128CBCSHA256 ...
	TLSECDHERSAWITHAES128CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"
	// TLSECDHERSAWITHAES256CBCSHA ...
	TLSECDHERSAWITHAES256CBCSHA ApplicationGatewaySslCipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"
	// TLSECDHERSAWITHAES256CBCSHA384 ...
	TLSECDHERSAWITHAES256CBCSHA384 ApplicationGatewaySslCipherSuite = "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"
	// TLSRSAWITH3DESEDECBCSHA ...
	TLSRSAWITH3DESEDECBCSHA ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_3DES_EDE_CBC_SHA"
	// TLSRSAWITHAES128CBCSHA ...
	TLSRSAWITHAES128CBCSHA ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_128_CBC_SHA"
	// TLSRSAWITHAES128CBCSHA256 ...
	TLSRSAWITHAES128CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_128_CBC_SHA256"
	// TLSRSAWITHAES128GCMSHA256 ...
	TLSRSAWITHAES128GCMSHA256 ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_128_GCM_SHA256"
	// TLSRSAWITHAES256CBCSHA ...
	TLSRSAWITHAES256CBCSHA ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_256_CBC_SHA"
	// TLSRSAWITHAES256CBCSHA256 ...
	TLSRSAWITHAES256CBCSHA256 ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_256_CBC_SHA256"
	// TLSRSAWITHAES256GCMSHA384 ...
	TLSRSAWITHAES256GCMSHA384 ApplicationGatewaySslCipherSuite = "TLS_RSA_WITH_AES_256_GCM_SHA384"
)

// PossibleApplicationGatewaySslCipherSuiteValues returns an array of possible values for the ApplicationGatewaySslCipherSuite const type.
func PossibleApplicationGatewaySslCipherSuiteValues() []ApplicationGatewaySslCipherSuite {
	return []ApplicationGatewaySslCipherSuite{TLSDHEDSSWITHAES128CBCSHA, TLSDHEDSSWITHAES128CBCSHA256, TLSDHEDSSWITHAES256CBCSHA, TLSDHEDSSWITHAES256CBCSHA256, TLSDHERSAWITHAES128CBCSHA, TLSDHERSAWITHAES128GCMSHA256, TLSDHERSAWITHAES256CBCSHA, TLSDHERSAWITHAES256GCMSHA384, TLSECDHEECDSAWITHAES128CBCSHA, TLSECDHEECDSAWITHAES128CBCSHA256, TLSECDHEECDSAWITHAES128GCMSHA256, TLSECDHEECDSAWITHAES256CBCSHA, TLSECDHEECDSAWITHAES256CBCSHA384, TLSECDHEECDSAWITHAES256GCMSHA384, TLSECDHERSAWITHAES128CBCSHA, TLSECDHERSAWITHAES128CBCSHA256, TLSECDHERSAWITHAES256CBCSHA, TLSECDHERSAWITHAES256CBCSHA384, TLSRSAWITH3DESEDECBCSHA, TLSRSAWITHAES128CBCSHA, TLSRSAWITHAES128CBCSHA256, TLSRSAWITHAES128GCMSHA256, TLSRSAWITHAES256CBCSHA, TLSRSAWITHAES256CBCSHA256, TLSRSAWITHAES256GCMSHA384}
}

// ApplicationGatewaySslPolicyName enumerates the values for application gateway ssl policy name.
type ApplicationGatewaySslPolicyName string

const (
	// AppGwSslPolicy20150501 ...
	AppGwSslPolicy20150501 ApplicationGatewaySslPolicyName = "AppGwSslPolicy20150501"
	// AppGwSslPolicy20170401 ...
	AppGwSslPolicy20170401 ApplicationGatewaySslPolicyName = "AppGwSslPolicy20170401"
	// AppGwSslPolicy20170401S ...
	AppGwSslPolicy20170401S ApplicationGatewaySslPolicyName = "AppGwSslPolicy20170401S"
)

// PossibleApplicationGatewaySslPolicyNameValues returns an array of possible values for the ApplicationGatewaySslPolicyName const type.
func PossibleApplicationGatewaySslPolicyNameValues() []ApplicationGatewaySslPolicyName {
	return []ApplicationGatewaySslPolicyName{AppGwSslPolicy20150501, AppGwSslPolicy20170401, AppGwSslPolicy20170401S}
}

// ApplicationGatewaySslPolicyType enumerates the values for application gateway ssl policy type.
type ApplicationGatewaySslPolicyType string

const (
	// Custom ...
	Custom ApplicationGatewaySslPolicyType = "Custom"
	// Predefined ...
	Predefined ApplicationGatewaySslPolicyType = "Predefined"
)

// PossibleApplicationGatewaySslPolicyTypeValues returns an array of possible values for the ApplicationGatewaySslPolicyType const type.
func PossibleApplicationGatewaySslPolicyTypeValues() []ApplicationGatewaySslPolicyType {
	return []ApplicationGatewaySslPolicyType{Custom, Predefined}
}

// ApplicationGatewaySslProtocol enumerates the values for application gateway ssl protocol.
type ApplicationGatewaySslProtocol string

const (
	// TLSv10 ...
	TLSv10 ApplicationGatewaySslProtocol = "TLSv1_0"
	// TLSv11 ...
	TLSv11 ApplicationGatewaySslProtocol = "TLSv1_1"
	// TLSv12 ...
	TLSv12 ApplicationGatewaySslProtocol = "TLSv1_2"
)

// PossibleApplicationGatewaySslProtocolValues returns an array of possible values for the ApplicationGatewaySslProtocol const type.
func PossibleApplicationGatewaySslProtocolValues() []ApplicationGatewaySslProtocol {
	return []ApplicationGatewaySslProtocol{TLSv10, TLSv11, TLSv12}
}

// ApplicationGatewayTier enumerates the values for application gateway tier.
type ApplicationGatewayTier string

const (
	// Standard ...
	Standard ApplicationGatewayTier = "Standard"
	// WAF ...
	WAF ApplicationGatewayTier = "WAF"
)

// PossibleApplicationGatewayTierValues returns an array of possible values for the ApplicationGatewayTier const type.
func PossibleApplicationGatewayTierValues() []ApplicationGatewayTier {
	return []ApplicationGatewayTier{Standard, WAF}
}

// AssociationType enumerates the values for association type.
type AssociationType string

const (
	// Associated ...
	Associated AssociationType = "Associated"
	// Contains ...
	Contains AssociationType = "Contains"
)

// PossibleAssociationTypeValues returns an array of possible values for the AssociationType const type.
func PossibleAssociationTypeValues() []AssociationType {
	return []AssociationType{Associated, Contains}
}

// AuthenticationMethod enumerates the values for authentication method.
type AuthenticationMethod string

const (
	// EAPMSCHAPv2 ...
	EAPMSCHAPv2 AuthenticationMethod = "EAPMSCHAPv2"
	// EAPTLS ...
	EAPTLS AuthenticationMethod = "EAPTLS"
)

// PossibleAuthenticationMethodValues returns an array of possible values for the AuthenticationMethod const type.
func PossibleAuthenticationMethodValues() []AuthenticationMethod {
	return []AuthenticationMethod{EAPMSCHAPv2, EAPTLS}
}

// AuthorizationUseStatus enumerates the values for authorization use status.
type AuthorizationUseStatus string

const (
	// Available ...
	Available AuthorizationUseStatus = "Available"
	// InUse ...
	InUse AuthorizationUseStatus = "InUse"
)

// PossibleAuthorizationUseStatusValues returns an array of possible values for the AuthorizationUseStatus const type.
func PossibleAuthorizationUseStatusValues() []AuthorizationUseStatus {
	return []AuthorizationUseStatus{Available, InUse}
}

// BgpPeerState enumerates the values for bgp peer state.
type BgpPeerState string

const (
	// BgpPeerStateConnected ...
	BgpPeerStateConnected BgpPeerState = "Connected"
	// BgpPeerStateConnecting ...
	BgpPeerStateConnecting BgpPeerState = "Connecting"
	// BgpPeerStateIdle ...
	BgpPeerStateIdle BgpPeerState = "Idle"
	// BgpPeerStateStopped ...
	BgpPeerStateStopped BgpPeerState = "Stopped"
	// BgpPeerStateUnknown ...
	BgpPeerStateUnknown BgpPeerState = "Unknown"
)

// PossibleBgpPeerStateValues returns an array of possible values for the BgpPeerState const type.
func PossibleBgpPeerStateValues() []BgpPeerState {
	return []BgpPeerState{BgpPeerStateConnected, BgpPeerStateConnecting, BgpPeerStateIdle, BgpPeerStateStopped, BgpPeerStateUnknown}
}

// ConnectionStatus enumerates the values for connection status.
type ConnectionStatus string

const (
	// ConnectionStatusConnected ...
	ConnectionStatusConnected ConnectionStatus = "Connected"
	// ConnectionStatusDegraded ...
	ConnectionStatusDegraded ConnectionStatus = "Degraded"
	// ConnectionStatusDisconnected ...
	ConnectionStatusDisconnected ConnectionStatus = "Disconnected"
	// ConnectionStatusUnknown ...
	ConnectionStatusUnknown ConnectionStatus = "Unknown"
)

// PossibleConnectionStatusValues returns an array of possible values for the ConnectionStatus const type.
func PossibleConnectionStatusValues() []ConnectionStatus {
	return []ConnectionStatus{ConnectionStatusConnected, ConnectionStatusDegraded, ConnectionStatusDisconnected, ConnectionStatusUnknown}
}

// DhGroup enumerates the values for dh group.
type DhGroup string

const (
	// DHGroup1 ...
	DHGroup1 DhGroup = "DHGroup1"
	// DHGroup14 ...
	DHGroup14 DhGroup = "DHGroup14"
	// DHGroup2 ...
	DHGroup2 DhGroup = "DHGroup2"
	// DHGroup2048 ...
	DHGroup2048 DhGroup = "DHGroup2048"
	// DHGroup24 ...
	DHGroup24 DhGroup = "DHGroup24"
	// ECP256 ...
	ECP256 DhGroup = "ECP256"
	// ECP384 ...
	ECP384 DhGroup = "ECP384"
	// None ...
	None DhGroup = "None"
)

// PossibleDhGroupValues returns an array of possible values for the DhGroup const type.
func PossibleDhGroupValues() []DhGroup {
	return []DhGroup{DHGroup1, DHGroup14, DHGroup2, DHGroup2048, DHGroup24, ECP256, ECP384, None}
}

// Direction enumerates the values for direction.
type Direction string

const (
	// Inbound ...
	Inbound Direction = "Inbound"
	// Outbound ...
	Outbound Direction = "Outbound"
)

// PossibleDirectionValues returns an array of possible values for the Direction const type.
func PossibleDirectionValues() []Direction {
	return []Direction{Inbound, Outbound}
}

// EffectiveRouteSource enumerates the values for effective route source.
type EffectiveRouteSource string

const (
	// EffectiveRouteSourceDefault ...
	EffectiveRouteSourceDefault EffectiveRouteSource = "Default"
	// EffectiveRouteSourceUnknown ...
	EffectiveRouteSourceUnknown EffectiveRouteSource = "Unknown"
	// EffectiveRouteSourceUser ...
	EffectiveRouteSourceUser EffectiveRouteSource = "User"
	// EffectiveRouteSourceVirtualNetworkGateway ...
	EffectiveRouteSourceVirtualNetworkGateway EffectiveRouteSource = "VirtualNetworkGateway"
)

// PossibleEffectiveRouteSourceValues returns an array of possible values for the EffectiveRouteSource const type.
func PossibleEffectiveRouteSourceValues() []EffectiveRouteSource {
	return []EffectiveRouteSource{EffectiveRouteSourceDefault, EffectiveRouteSourceUnknown, EffectiveRouteSourceUser, EffectiveRouteSourceVirtualNetworkGateway}
}

// EffectiveRouteState enumerates the values for effective route state.
type EffectiveRouteState string

const (
	// Active ...
	Active EffectiveRouteState = "Active"
	// Invalid ...
	Invalid EffectiveRouteState = "Invalid"
)

// PossibleEffectiveRouteStateValues returns an array of possible values for the EffectiveRouteState const type.
func PossibleEffectiveRouteStateValues() []EffectiveRouteState {
	return []EffectiveRouteState{Active, Invalid}
}

// EffectiveSecurityRuleProtocol enumerates the values for effective security rule protocol.
type EffectiveSecurityRuleProtocol string

const (
	// All ...
	All EffectiveSecurityRuleProtocol = "All"
	// TCP ...
	TCP EffectiveSecurityRuleProtocol = "Tcp"
	// UDP ...
	UDP EffectiveSecurityRuleProtocol = "Udp"
)

// PossibleEffectiveSecurityRuleProtocolValues returns an array of possible values for the EffectiveSecurityRuleProtocol const type.
func PossibleEffectiveSecurityRuleProtocolValues() []EffectiveSecurityRuleProtocol {
	return []EffectiveSecurityRuleProtocol{All, TCP, UDP}
}

// ExpressRouteCircuitPeeringAdvertisedPublicPrefixState enumerates the values for express route circuit
// peering advertised public prefix state.
type ExpressRouteCircuitPeeringAdvertisedPublicPrefixState string

const (
	// Configured ...
	Configured ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "Configured"
	// Configuring ...
	Configuring ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "Configuring"
	// NotConfigured ...
	NotConfigured ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "NotConfigured"
	// ValidationNeeded ...
	ValidationNeeded ExpressRouteCircuitPeeringAdvertisedPublicPrefixState = "ValidationNeeded"
)

// PossibleExpressRouteCircuitPeeringAdvertisedPublicPrefixStateValues returns an array of possible values for the ExpressRouteCircuitPeeringAdvertisedPublicPrefixState const type.
func PossibleExpressRouteCircuitPeeringAdvertisedPublicPrefixStateValues() []ExpressRouteCircuitPeeringAdvertisedPublicPrefixState {
	return []ExpressRouteCircuitPeeringAdvertisedPublicPrefixState{Configured, Configuring, NotConfigured, ValidationNeeded}
}

// ExpressRouteCircuitPeeringState enumerates the values for express route circuit peering state.
type ExpressRouteCircuitPeeringState string

const (
	// ExpressRouteCircuitPeeringStateDisabled ...
	ExpressRouteCircuitPeeringStateDisabled ExpressRouteCircuitPeeringState = "Disabled"
	// ExpressRouteCircuitPeeringStateEnabled ...
	ExpressRouteCircuitPeeringStateEnabled ExpressRouteCircuitPeeringState = "Enabled"
)

// PossibleExpressRouteCircuitPeeringStateValues returns an array of possible values for the ExpressRouteCircuitPeeringState const type.
func PossibleExpressRouteCircuitPeeringStateValues() []ExpressRouteCircuitPeeringState {
	return []ExpressRouteCircuitPeeringState{ExpressRouteCircuitPeeringStateDisabled, ExpressRouteCircuitPeeringStateEnabled}
}

// ExpressRouteCircuitPeeringType enumerates the values for express route circuit peering type.
type ExpressRouteCircuitPeeringType string

const (
	// AzurePrivatePeering ...
	AzurePrivatePeering ExpressRouteCircuitPeeringType = "AzurePrivatePeering"
	// AzurePublicPeering ...
	AzurePublicPeering ExpressRouteCircuitPeeringType = "AzurePublicPeering"
	// MicrosoftPeering ...
	MicrosoftPeering ExpressRouteCircuitPeeringType = "MicrosoftPeering"
)

// PossibleExpressRouteCircuitPeeringTypeValues returns an array of possible values for the ExpressRouteCircuitPeeringType const type.
func PossibleExpressRouteCircuitPeeringTypeValues() []ExpressRouteCircuitPeeringType {
	return []ExpressRouteCircuitPeeringType{AzurePrivatePeering, AzurePublicPeering, MicrosoftPeering}
}

// ExpressRouteCircuitSkuFamily enumerates the values for express route circuit sku family.
type ExpressRouteCircuitSkuFamily string

const (
	// MeteredData ...
	MeteredData ExpressRouteCircuitSkuFamily = "MeteredData"
	// UnlimitedData ...
	UnlimitedData ExpressRouteCircuitSkuFamily = "UnlimitedData"
)

// PossibleExpressRouteCircuitSkuFamilyValues returns an array of possible values for the ExpressRouteCircuitSkuFamily const type.
func PossibleExpressRouteCircuitSkuFamilyValues() []ExpressRouteCircuitSkuFamily {
	return []ExpressRouteCircuitSkuFamily{MeteredData, UnlimitedData}
}

// ExpressRouteCircuitSkuTier enumerates the values for express route circuit sku tier.
type ExpressRouteCircuitSkuTier string

const (
	// ExpressRouteCircuitSkuTierPremium ...
	ExpressRouteCircuitSkuTierPremium ExpressRouteCircuitSkuTier = "Premium"
	// ExpressRouteCircuitSkuTierStandard ...
	ExpressRouteCircuitSkuTierStandard ExpressRouteCircuitSkuTier = "Standard"
)

// PossibleExpressRouteCircuitSkuTierValues returns an array of possible values for the ExpressRouteCircuitSkuTier const type.
func PossibleExpressRouteCircuitSkuTierValues() []ExpressRouteCircuitSkuTier {
	return []ExpressRouteCircuitSkuTier{ExpressRouteCircuitSkuTierPremium, ExpressRouteCircuitSkuTierStandard}
}

// IkeEncryption enumerates the values for ike encryption.
type IkeEncryption string

const (
	// AES128 ...
	AES128 IkeEncryption = "AES128"
	// AES192 ...
	AES192 IkeEncryption = "AES192"
	// AES256 ...
	AES256 IkeEncryption = "AES256"
	// DES ...
	DES IkeEncryption = "DES"
	// DES3 ...
	DES3 IkeEncryption = "DES3"
)

// PossibleIkeEncryptionValues returns an array of possible values for the IkeEncryption const type.
func PossibleIkeEncryptionValues() []IkeEncryption {
	return []IkeEncryption{AES128, AES192, AES256, DES, DES3}
}

// IkeIntegrity enumerates the values for ike integrity.
type IkeIntegrity string

const (
	// MD5 ...
	MD5 IkeIntegrity = "MD5"
	// SHA1 ...
	SHA1 IkeIntegrity = "SHA1"
	// SHA256 ...
	SHA256 IkeIntegrity = "SHA256"
	// SHA384 ...
	SHA384 IkeIntegrity = "SHA384"
)

// PossibleIkeIntegrityValues returns an array of possible values for the IkeIntegrity const type.
func PossibleIkeIntegrityValues() []IkeIntegrity {
	return []IkeIntegrity{MD5, SHA1, SHA256, SHA384}
}

// IPAllocationMethod enumerates the values for ip allocation method.
type IPAllocationMethod string

const (
	// Dynamic ...
	Dynamic IPAllocationMethod = "Dynamic"
	// Static ...
	Static IPAllocationMethod = "Static"
)

// PossibleIPAllocationMethodValues returns an array of possible values for the IPAllocationMethod const type.
func PossibleIPAllocationMethodValues() []IPAllocationMethod {
	return []IPAllocationMethod{Dynamic, Static}
}

// IpsecEncryption enumerates the values for ipsec encryption.
type IpsecEncryption string

const (
	// IpsecEncryptionAES128 ...
	IpsecEncryptionAES128 IpsecEncryption = "AES128"
	// IpsecEncryptionAES192 ...
	IpsecEncryptionAES192 IpsecEncryption = "AES192"
	// IpsecEncryptionAES256 ...
	IpsecEncryptionAES256 IpsecEncryption = "AES256"
	// IpsecEncryptionDES ...
	IpsecEncryptionDES IpsecEncryption = "DES"
	// IpsecEncryptionDES3 ...
	IpsecEncryptionDES3 IpsecEncryption = "DES3"
	// IpsecEncryptionGCMAES128 ...
	IpsecEncryptionGCMAES128 IpsecEncryption = "GCMAES128"
	// IpsecEncryptionGCMAES192 ...
	IpsecEncryptionGCMAES192 IpsecEncryption = "GCMAES192"
	// IpsecEncryptionGCMAES256 ...
	IpsecEncryptionGCMAES256 IpsecEncryption = "GCMAES256"
	// IpsecEncryptionNone ...
	IpsecEncryptionNone IpsecEncryption = "None"
)

// PossibleIpsecEncryptionValues returns an array of possible values for the IpsecEncryption const type.
func PossibleIpsecEncryptionValues() []IpsecEncryption {
	return []IpsecEncryption{IpsecEncryptionAES128, IpsecEncryptionAES192, IpsecEncryptionAES256, IpsecEncryptionDES, IpsecEncryptionDES3, IpsecEncryptionGCMAES128, IpsecEncryptionGCMAES192, IpsecEncryptionGCMAES256, IpsecEncryptionNone}
}

// IpsecIntegrity enumerates the values for ipsec integrity.
type IpsecIntegrity string

const (
	// IpsecIntegrityGCMAES128 ...
	IpsecIntegrityGCMAES128 IpsecIntegrity = "GCMAES128"
	// IpsecIntegrityGCMAES192 ...
	IpsecIntegrityGCMAES192 IpsecIntegrity = "GCMAES192"
	// IpsecIntegrityGCMAES256 ...
	IpsecIntegrityGCMAES256 IpsecIntegrity = "GCMAES256"
	// IpsecIntegrityMD5 ...
	IpsecIntegrityMD5 IpsecIntegrity = "MD5"
	// IpsecIntegritySHA1 ...
	IpsecIntegritySHA1 IpsecIntegrity = "SHA1"
	// IpsecIntegritySHA256 ...
	IpsecIntegritySHA256 IpsecIntegrity = "SHA256"
)

// PossibleIpsecIntegrityValues returns an array of possible values for the IpsecIntegrity const type.
func PossibleIpsecIntegrityValues() []IpsecIntegrity {
	return []IpsecIntegrity{IpsecIntegrityGCMAES128, IpsecIntegrityGCMAES192, IpsecIntegrityGCMAES256, IpsecIntegrityMD5, IpsecIntegritySHA1, IpsecIntegritySHA256}
}

// IPVersion enumerates the values for ip version.
type IPVersion string

const (
	// IPv4 ...
	IPv4 IPVersion = "IPv4"
	// IPv6 ...
	IPv6 IPVersion = "IPv6"
)

// PossibleIPVersionValues returns an array of possible values for the IPVersion const type.
func PossibleIPVersionValues() []IPVersion {
	return []IPVersion{IPv4, IPv6}
}

// IssueType enumerates the values for issue type.
type IssueType string

const (
	// IssueTypeAgentStopped ...
	IssueTypeAgentStopped IssueType = "AgentStopped"
	// IssueTypeDNSResolution ...
	IssueTypeDNSResolution IssueType = "DnsResolution"
	// IssueTypeGuestFirewall ...
	IssueTypeGuestFirewall IssueType = "GuestFirewall"
	// IssueTypeNetworkSecurityRule ...
	IssueTypeNetworkSecurityRule IssueType = "NetworkSecurityRule"
	// IssueTypePlatform ...
	IssueTypePlatform IssueType = "Platform"
	// IssueTypePortThrottled ...
	IssueTypePortThrottled IssueType = "PortThrottled"
	// IssueTypeSocketBind ...
	IssueTypeSocketBind IssueType = "SocketBind"
	// IssueTypeUnknown ...
	IssueTypeUnknown IssueType = "Unknown"
	// IssueTypeUserDefinedRoute ...
	IssueTypeUserDefinedRoute IssueType = "UserDefinedRoute"
)

// PossibleIssueTypeValues returns an array of possible values for the IssueType const type.
func PossibleIssueTypeValues() []IssueType {
	return []IssueType{IssueTypeAgentStopped, IssueTypeDNSResolution, IssueTypeGuestFirewall, IssueTypeNetworkSecurityRule, IssueTypePlatform, IssueTypePortThrottled, IssueTypeSocketBind, IssueTypeUnknown, IssueTypeUserDefinedRoute}
}

// LoadBalancerSkuName enumerates the values for load balancer sku name.
type LoadBalancerSkuName string

const (
	// LoadBalancerSkuNameBasic ...
	LoadBalancerSkuNameBasic LoadBalancerSkuName = "Basic"
	// LoadBalancerSkuNameStandard ...
	LoadBalancerSkuNameStandard LoadBalancerSkuName = "Standard"
)

// PossibleLoadBalancerSkuNameValues returns an array of possible values for the LoadBalancerSkuName const type.
func PossibleLoadBalancerSkuNameValues() []LoadBalancerSkuName {
	return []LoadBalancerSkuName{LoadBalancerSkuNameBasic, LoadBalancerSkuNameStandard}
}

// LoadDistribution enumerates the values for load distribution.
type LoadDistribution string

const (
	// Default ...
	Default LoadDistribution = "Default"
	// SourceIP ...
	SourceIP LoadDistribution = "SourceIP"
	// SourceIPProtocol ...
	SourceIPProtocol LoadDistribution = "SourceIPProtocol"
)

// PossibleLoadDistributionValues returns an array of possible values for the LoadDistribution const type.
func PossibleLoadDistributionValues() []LoadDistribution {
	return []LoadDistribution{Default, SourceIP, SourceIPProtocol}
}

// NextHopType enumerates the values for next hop type.
type NextHopType string

const (
	// NextHopTypeHyperNetGateway ...
	NextHopTypeHyperNetGateway NextHopType = "HyperNetGateway"
	// NextHopTypeInternet ...
	NextHopTypeInternet NextHopType = "Internet"
	// NextHopTypeNone ...
	NextHopTypeNone NextHopType = "None"
	// NextHopTypeVirtualAppliance ...
	NextHopTypeVirtualAppliance NextHopType = "VirtualAppliance"
	// NextHopTypeVirtualNetworkGateway ...
	NextHopTypeVirtualNetworkGateway NextHopType = "VirtualNetworkGateway"
	// NextHopTypeVnetLocal ...
	NextHopTypeVnetLocal NextHopType = "VnetLocal"
)

// PossibleNextHopTypeValues returns an array of possible values for the NextHopType const type.
func PossibleNextHopTypeValues() []NextHopType {
	return []NextHopType{NextHopTypeHyperNetGateway, NextHopTypeInternet, NextHopTypeNone, NextHopTypeVirtualAppliance, NextHopTypeVirtualNetworkGateway, NextHopTypeVnetLocal}
}

// OperationStatus enumerates the values for operation status.
type OperationStatus string

const (
	// Failed ...
	Failed OperationStatus = "Failed"
	// InProgress ...
	InProgress OperationStatus = "InProgress"
	// Succeeded ...
	Succeeded OperationStatus = "Succeeded"
)

// PossibleOperationStatusValues returns an array of possible values for the OperationStatus const type.
func PossibleOperationStatusValues() []OperationStatus {
	return []OperationStatus{Failed, InProgress, Succeeded}
}

// Origin enumerates the values for origin.
type Origin string

const (
	// OriginInbound ...
	OriginInbound Origin = "Inbound"
	// OriginLocal ...
	OriginLocal Origin = "Local"
	// OriginOutbound ...
	OriginOutbound Origin = "Outbound"
)

// PossibleOriginValues returns an array of possible values for the Origin const type.
func PossibleOriginValues() []Origin {
	return []Origin{OriginInbound, OriginLocal, OriginOutbound}
}

// PcError enumerates the values for pc error.
type PcError string

const (
	// AgentStopped ...
	AgentStopped PcError = "AgentStopped"
	// CaptureFailed ...
	CaptureFailed PcError = "CaptureFailed"
	// InternalError ...
	InternalError PcError = "InternalError"
	// LocalFileFailed ...
	LocalFileFailed PcError = "LocalFileFailed"
	// StorageFailed ...
	StorageFailed PcError = "StorageFailed"
)

// PossiblePcErrorValues returns an array of possible values for the PcError const type.
func PossiblePcErrorValues() []PcError {
	return []PcError{AgentStopped, CaptureFailed, InternalError, LocalFileFailed, StorageFailed}
}

// PcProtocol enumerates the values for pc protocol.
type PcProtocol string

const (
	// PcProtocolAny ...
	PcProtocolAny PcProtocol = "Any"
	// PcProtocolTCP ...
	PcProtocolTCP PcProtocol = "TCP"
	// PcProtocolUDP ...
	PcProtocolUDP PcProtocol = "UDP"
)

// PossiblePcProtocolValues returns an array of possible values for the PcProtocol const type.
func PossiblePcProtocolValues() []PcProtocol {
	return []PcProtocol{PcProtocolAny, PcProtocolTCP, PcProtocolUDP}
}

// PcStatus enumerates the values for pc status.
type PcStatus string

const (
	// PcStatusError ...
	PcStatusError PcStatus = "Error"
	// PcStatusNotStarted ...
	PcStatusNotStarted PcStatus = "NotStarted"
	// PcStatusRunning ...
	PcStatusRunning PcStatus = "Running"
	// PcStatusStopped ...
	PcStatusStopped PcStatus = "Stopped"
	// PcStatusUnknown ...
	PcStatusUnknown PcStatus = "Unknown"
)

// PossiblePcStatusValues returns an array of possible values for the PcStatus const type.
func PossiblePcStatusValues() []PcStatus {
	return []PcStatus{PcStatusError, PcStatusNotStarted, PcStatusRunning, PcStatusStopped, PcStatusUnknown}
}

// PfsGroup enumerates the values for pfs group.
type PfsGroup string

const (
	// PfsGroupECP256 ...
	PfsGroupECP256 PfsGroup = "ECP256"
	// PfsGroupECP384 ...
	PfsGroupECP384 PfsGroup = "ECP384"
	// PfsGroupNone ...
	PfsGroupNone PfsGroup = "None"
	// PfsGroupPFS1 ...
	PfsGroupPFS1 PfsGroup = "PFS1"
	// PfsGroupPFS2 ...
	PfsGroupPFS2 PfsGroup = "PFS2"
	// PfsGroupPFS2048 ...
	PfsGroupPFS2048 PfsGroup = "PFS2048"
	// PfsGroupPFS24 ...
	PfsGroupPFS24 PfsGroup = "PFS24"
)

// PossiblePfsGroupValues returns an array of possible values for the PfsGroup const type.
func PossiblePfsGroupValues() []PfsGroup {
	return []PfsGroup{PfsGroupECP256, PfsGroupECP384, PfsGroupNone, PfsGroupPFS1, PfsGroupPFS2, PfsGroupPFS2048, PfsGroupPFS24}
}

// ProbeProtocol enumerates the values for probe protocol.
type ProbeProtocol string

const (
	// ProbeProtocolHTTP ...
	ProbeProtocolHTTP ProbeProtocol = "Http"
	// ProbeProtocolTCP ...
	ProbeProtocolTCP ProbeProtocol = "Tcp"
)

// PossibleProbeProtocolValues returns an array of possible values for the ProbeProtocol const type.
func PossibleProbeProtocolValues() []ProbeProtocol {
	return []ProbeProtocol{ProbeProtocolHTTP, ProbeProtocolTCP}
}

// ProcessorArchitecture enumerates the values for processor architecture.
type ProcessorArchitecture string

const (
	// Amd64 ...
	Amd64 ProcessorArchitecture = "Amd64"
	// X86 ...
	X86 ProcessorArchitecture = "X86"
)

// PossibleProcessorArchitectureValues returns an array of possible values for the ProcessorArchitecture const type.
func PossibleProcessorArchitectureValues() []ProcessorArchitecture {
	return []ProcessorArchitecture{Amd64, X86}
}

// Protocol enumerates the values for protocol.
type Protocol string

const (
	// ProtocolTCP ...
	ProtocolTCP Protocol = "TCP"
	// ProtocolUDP ...
	ProtocolUDP Protocol = "UDP"
)

// PossibleProtocolValues returns an array of possible values for the Protocol const type.
func PossibleProtocolValues() []Protocol {
	return []Protocol{ProtocolTCP, ProtocolUDP}
}

// ProvisioningState enumerates the values for provisioning state.
type ProvisioningState string

const (
	// ProvisioningStateDeleting ...
	ProvisioningStateDeleting ProvisioningState = "Deleting"
	// ProvisioningStateFailed ...
	ProvisioningStateFailed ProvisioningState = "Failed"
	// ProvisioningStateSucceeded ...
	ProvisioningStateSucceeded ProvisioningState = "Succeeded"
	// ProvisioningStateUpdating ...
	ProvisioningStateUpdating ProvisioningState = "Updating"
)

// PossibleProvisioningStateValues returns an array of possible values for the ProvisioningState const type.
func PossibleProvisioningStateValues() []ProvisioningState {
	return []ProvisioningState{ProvisioningStateDeleting, ProvisioningStateFailed, ProvisioningStateSucceeded, ProvisioningStateUpdating}
}

// PublicIPAddressSkuName enumerates the values for public ip address sku name.
type PublicIPAddressSkuName string

const (
	// PublicIPAddressSkuNameBasic ...
	PublicIPAddressSkuNameBasic PublicIPAddressSkuName = "Basic"
	// PublicIPAddressSkuNameStandard ...
	PublicIPAddressSkuNameStandard PublicIPAddressSkuName = "Standard"
)

// PossiblePublicIPAddressSkuNameValues returns an array of possible values for the PublicIPAddressSkuName const type.
func PossiblePublicIPAddressSkuNameValues() []PublicIPAddressSkuName {
	return []PublicIPAddressSkuName{PublicIPAddressSkuNameBasic, PublicIPAddressSkuNameStandard}
}

// RouteNextHopType enumerates the values for route next hop type.
type RouteNextHopType string

const (
	// RouteNextHopTypeInternet ...
	RouteNextHopTypeInternet RouteNextHopType = "Internet"
	// RouteNextHopTypeNone ...
	RouteNextHopTypeNone RouteNextHopType = "None"
	// RouteNextHopTypeVirtualAppliance ...
	RouteNextHopTypeVirtualAppliance RouteNextHopType = "VirtualAppliance"
	// RouteNextHopTypeVirtualNetworkGateway ...
	RouteNextHopTypeVirtualNetworkGateway RouteNextHopType = "VirtualNetworkGateway"
	// RouteNextHopTypeVnetLocal ...
	RouteNextHopTypeVnetLocal RouteNextHopType = "VnetLocal"
)

// PossibleRouteNextHopTypeValues returns an array of possible values for the RouteNextHopType const type.
func PossibleRouteNextHopTypeValues() []RouteNextHopType {
	return []RouteNextHopType{RouteNextHopTypeInternet, RouteNextHopTypeNone, RouteNextHopTypeVirtualAppliance, RouteNextHopTypeVirtualNetworkGateway, RouteNextHopTypeVnetLocal}
}

// SecurityRuleAccess enumerates the values for security rule access.
type SecurityRuleAccess string

const (
	// SecurityRuleAccessAllow ...
	SecurityRuleAccessAllow SecurityRuleAccess = "Allow"
	// SecurityRuleAccessDeny ...
	SecurityRuleAccessDeny SecurityRuleAccess = "Deny"
)

// PossibleSecurityRuleAccessValues returns an array of possible values for the SecurityRuleAccess const type.
func PossibleSecurityRuleAccessValues() []SecurityRuleAccess {
	return []SecurityRuleAccess{SecurityRuleAccessAllow, SecurityRuleAccessDeny}
}

// SecurityRuleDirection enumerates the values for security rule direction.
type SecurityRuleDirection string

const (
	// SecurityRuleDirectionInbound ...
	SecurityRuleDirectionInbound SecurityRuleDirection = "Inbound"
	// SecurityRuleDirectionOutbound ...
	SecurityRuleDirectionOutbound SecurityRuleDirection = "Outbound"
)

// PossibleSecurityRuleDirectionValues returns an array of possible values for the SecurityRuleDirection const type.
func PossibleSecurityRuleDirectionValues() []SecurityRuleDirection {
	return []SecurityRuleDirection{SecurityRuleDirectionInbound, SecurityRuleDirectionOutbound}
}

// SecurityRuleProtocol enumerates the values for security rule protocol.
type SecurityRuleProtocol string

const (
	// SecurityRuleProtocolAsterisk ...
	SecurityRuleProtocolAsterisk SecurityRuleProtocol = "*"
	// SecurityRuleProtocolTCP ...
	SecurityRuleProtocolTCP SecurityRuleProtocol = "Tcp"
	// SecurityRuleProtocolUDP ...
	SecurityRuleProtocolUDP SecurityRuleProtocol = "Udp"
)

// PossibleSecurityRuleProtocolValues returns an array of possible values for the SecurityRuleProtocol const type.
func PossibleSecurityRuleProtocolValues() []SecurityRuleProtocol {
	return []SecurityRuleProtocol{SecurityRuleProtocolAsterisk, SecurityRuleProtocolTCP, SecurityRuleProtocolUDP}
}

// ServiceProviderProvisioningState enumerates the values for service provider provisioning state.
type ServiceProviderProvisioningState string

const (
	// Deprovisioning ...
	Deprovisioning ServiceProviderProvisioningState = "Deprovisioning"
	// NotProvisioned ...
	NotProvisioned ServiceProviderProvisioningState = "NotProvisioned"
	// Provisioned ...
	Provisioned ServiceProviderProvisioningState = "Provisioned"
	// Provisioning ...
	Provisioning ServiceProviderProvisioningState = "Provisioning"
)

// PossibleServiceProviderProvisioningStateValues returns an array of possible values for the ServiceProviderProvisioningState const type.
func PossibleServiceProviderProvisioningStateValues() []ServiceProviderProvisioningState {
	return []ServiceProviderProvisioningState{Deprovisioning, NotProvisioned, Provisioned, Provisioning}
}

// Severity enumerates the values for severity.
type Severity string

const (
	// SeverityError ...
	SeverityError Severity = "Error"
	// SeverityWarning ...
	SeverityWarning Severity = "Warning"
)

// PossibleSeverityValues returns an array of possible values for the Severity const type.
func PossibleSeverityValues() []Severity {
	return []Severity{SeverityError, SeverityWarning}
}

// TransportProtocol enumerates the values for transport protocol.
type TransportProtocol string

const (
	// TransportProtocolAll ...
	TransportProtocolAll TransportProtocol = "All"
	// TransportProtocolTCP ...
	TransportProtocolTCP TransportProtocol = "Tcp"
	// TransportProtocolUDP ...
	TransportProtocolUDP TransportProtocol = "Udp"
)

// PossibleTransportProtocolValues returns an array of possible values for the TransportProtocol const type.
func PossibleTransportProtocolValues() []TransportProtocol {
	return []TransportProtocol{TransportProtocolAll, TransportProtocolTCP, TransportProtocolUDP}
}

// VirtualNetworkGatewayConnectionStatus enumerates the values for virtual network gateway connection status.
type VirtualNetworkGatewayConnectionStatus string

const (
	// VirtualNetworkGatewayConnectionStatusConnected ...
	VirtualNetworkGatewayConnectionStatusConnected VirtualNetworkGatewayConnectionStatus = "Connected"
	// VirtualNetworkGatewayConnectionStatusConnecting ...
	VirtualNetworkGatewayConnectionStatusConnecting VirtualNetworkGatewayConnectionStatus = "Connecting"
	// VirtualNetworkGatewayConnectionStatusNotConnected ...
	VirtualNetworkGatewayConnectionStatusNotConnected VirtualNetworkGatewayConnectionStatus = "NotConnected"
	// VirtualNetworkGatewayConnectionStatusUnknown ...
	VirtualNetworkGatewayConnectionStatusUnknown VirtualNetworkGatewayConnectionStatus = "Unknown"
)

// PossibleVirtualNetworkGatewayConnectionStatusValues returns an array of possible values for the VirtualNetworkGatewayConnectionStatus const type.
func PossibleVirtualNetworkGatewayConnectionStatusValues() []VirtualNetworkGatewayConnectionStatus {
	return []VirtualNetworkGatewayConnectionStatus{VirtualNetworkGatewayConnectionStatusConnected, VirtualNetworkGatewayConnectionStatusConnecting, VirtualNetworkGatewayConnectionStatusNotConnected, VirtualNetworkGatewayConnectionStatusUnknown}
}

// VirtualNetworkGatewayConnectionType enumerates the values for virtual network gateway connection type.
type VirtualNetworkGatewayConnectionType string

const (
	// ExpressRoute ...
	ExpressRoute VirtualNetworkGatewayConnectionType = "ExpressRoute"
	// IPsec ...
	IPsec VirtualNetworkGatewayConnectionType = "IPsec"
	// Vnet2Vnet ...
	Vnet2Vnet VirtualNetworkGatewayConnectionType = "Vnet2Vnet"
	// VPNClient ...
	VPNClient VirtualNetworkGatewayConnectionType = "VPNClient"
)

// PossibleVirtualNetworkGatewayConnectionTypeValues returns an array of possible values for the VirtualNetworkGatewayConnectionType const type.
func PossibleVirtualNetworkGatewayConnectionTypeValues() []VirtualNetworkGatewayConnectionType {
	return []VirtualNetworkGatewayConnectionType{ExpressRoute, IPsec, Vnet2Vnet, VPNClient}
}

// VirtualNetworkGatewaySkuName enumerates the values for virtual network gateway sku name.
type VirtualNetworkGatewaySkuName string

const (
	// VirtualNetworkGatewaySkuNameBasic ...
	VirtualNetworkGatewaySkuNameBasic VirtualNetworkGatewaySkuName = "Basic"
	// VirtualNetworkGatewaySkuNameHighPerformance ...
	VirtualNetworkGatewaySkuNameHighPerformance VirtualNetworkGatewaySkuName = "HighPerformance"
	// VirtualNetworkGatewaySkuNameStandard ...
	VirtualNetworkGatewaySkuNameStandard VirtualNetworkGatewaySkuName = "Standard"
	// VirtualNetworkGatewaySkuNameUltraPerformance ...
	VirtualNetworkGatewaySkuNameUltraPerformance VirtualNetworkGatewaySkuName = "UltraPerformance"
	// VirtualNetworkGatewaySkuNameVpnGw1 ...
	VirtualNetworkGatewaySkuNameVpnGw1 VirtualNetworkGatewaySkuName = "VpnGw1"
	// VirtualNetworkGatewaySkuNameVpnGw2 ...
	VirtualNetworkGatewaySkuNameVpnGw2 VirtualNetworkGatewaySkuName = "VpnGw2"
	// VirtualNetworkGatewaySkuNameVpnGw3 ...
	VirtualNetworkGatewaySkuNameVpnGw3 VirtualNetworkGatewaySkuName = "VpnGw3"
)

// PossibleVirtualNetworkGatewaySkuNameValues returns an array of possible values for the VirtualNetworkGatewaySkuName const type.
func PossibleVirtualNetworkGatewaySkuNameValues() []VirtualNetworkGatewaySkuName {
	return []VirtualNetworkGatewaySkuName{VirtualNetworkGatewaySkuNameBasic, VirtualNetworkGatewaySkuNameHighPerformance, VirtualNetworkGatewaySkuNameStandard, VirtualNetworkGatewaySkuNameUltraPerformance, VirtualNetworkGatewaySkuNameVpnGw1, VirtualNetworkGatewaySkuNameVpnGw2, VirtualNetworkGatewaySkuNameVpnGw3}
}

// VirtualNetworkGatewaySkuTier enumerates the values for virtual network gateway sku tier.
type VirtualNetworkGatewaySkuTier string

const (
	// VirtualNetworkGatewaySkuTierBasic ...
	VirtualNetworkGatewaySkuTierBasic VirtualNetworkGatewaySkuTier = "Basic"
	// VirtualNetworkGatewaySkuTierHighPerformance ...
	VirtualNetworkGatewaySkuTierHighPerformance VirtualNetworkGatewaySkuTier = "HighPerformance"
	// VirtualNetworkGatewaySkuTierStandard ...
	VirtualNetworkGatewaySkuTierStandard VirtualNetworkGatewaySkuTier = "Standard"
	// VirtualNetworkGatewaySkuTierUltraPerformance ...
	VirtualNetworkGatewaySkuTierUltraPerformance VirtualNetworkGatewaySkuTier = "UltraPerformance"
	// VirtualNetworkGatewaySkuTierVpnGw1 ...
	VirtualNetworkGatewaySkuTierVpnGw1 VirtualNetworkGatewaySkuTier = "VpnGw1"
	// VirtualNetworkGatewaySkuTierVpnGw2 ...
	VirtualNetworkGatewaySkuTierVpnGw2 VirtualNetworkGatewaySkuTier = "VpnGw2"
	// VirtualNetworkGatewaySkuTierVpnGw3 ...
	VirtualNetworkGatewaySkuTierVpnGw3 VirtualNetworkGatewaySkuTier = "VpnGw3"
)

// PossibleVirtualNetworkGatewaySkuTierValues returns an array of possible values for the VirtualNetworkGatewaySkuTier const type.
func PossibleVirtualNetworkGatewaySkuTierValues() []VirtualNetworkGatewaySkuTier {
	return []VirtualNetworkGatewaySkuTier{VirtualNetworkGatewaySkuTierBasic, VirtualNetworkGatewaySkuTierHighPerformance, VirtualNetworkGatewaySkuTierStandard, VirtualNetworkGatewaySkuTierUltraPerformance, VirtualNetworkGatewaySkuTierVpnGw1, VirtualNetworkGatewaySkuTierVpnGw2, VirtualNetworkGatewaySkuTierVpnGw3}
}

// VirtualNetworkGatewayType enumerates the values for virtual network gateway type.
type VirtualNetworkGatewayType string

const (
	// VirtualNetworkGatewayTypeExpressRoute ...
	VirtualNetworkGatewayTypeExpressRoute VirtualNetworkGatewayType = "ExpressRoute"
	// VirtualNetworkGatewayTypeVpn ...
	VirtualNetworkGatewayTypeVpn VirtualNetworkGatewayType = "Vpn"
)

// PossibleVirtualNetworkGatewayTypeValues returns an array of possible values for the VirtualNetworkGatewayType const type.
func PossibleVirtualNetworkGatewayTypeValues() []VirtualNetworkGatewayType {
	return []VirtualNetworkGatewayType{VirtualNetworkGatewayTypeExpressRoute, VirtualNetworkGatewayTypeVpn}
}

// VirtualNetworkPeeringState enumerates the values for virtual network peering state.
type VirtualNetworkPeeringState string

const (
	// Connected ...
	Connected VirtualNetworkPeeringState = "Connected"
	// Disconnected ...
	Disconnected VirtualNetworkPeeringState = "Disconnected"
	// Initiated ...
	Initiated VirtualNetworkPeeringState = "Initiated"
)

// PossibleVirtualNetworkPeeringStateValues returns an array of possible values for the VirtualNetworkPeeringState const type.
func PossibleVirtualNetworkPeeringStateValues() []VirtualNetworkPeeringState {
	return []VirtualNetworkPeeringState{Connected, Disconnected, Initiated}
}

// VpnClientProtocol enumerates the values for vpn client protocol.
type VpnClientProtocol string

const (
	// IkeV2 ...
	IkeV2 VpnClientProtocol = "IkeV2"
	// SSTP ...
	SSTP VpnClientProtocol = "SSTP"
)

// PossibleVpnClientProtocolValues returns an array of possible values for the VpnClientProtocol const type.
func PossibleVpnClientProtocolValues() []VpnClientProtocol {
	return []VpnClientProtocol{IkeV2, SSTP}
}

// VpnType enumerates the values for vpn type.
type VpnType string

const (
	// PolicyBased ...
	PolicyBased VpnType = "PolicyBased"
	// RouteBased ...
	RouteBased VpnType = "RouteBased"
)

// PossibleVpnTypeValues returns an array of possible values for the VpnType const type.
func PossibleVpnTypeValues() []VpnType {
	return []VpnType{PolicyBased, RouteBased}
}

// AddressSpace addressSpace contains an array of IP address ranges that can be used by subnets of the
// virtual network.
type AddressSpace struct {
	// AddressPrefixes - A list of address blocks reserved for this virtual network in CIDR notation.
	AddressPrefixes *[]string `json:"addressPrefixes,omitempty"`
}

// ApplicationGateway application gateway resource
type ApplicationGateway struct {
	autorest.Response                   `json:"-"`
	*ApplicationGatewayPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ApplicationGateway.
func (ag ApplicationGateway) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ag.ApplicationGatewayPropertiesFormat != nil {
		objectMap["properties"] = ag.ApplicationGatewayPropertiesFormat
	}
	if ag.Etag != nil {
		objectMap["etag"] = ag.Etag
	}
	if ag.ID != nil {
		objectMap["id"] = ag.ID
	}
	if ag.Name != nil {
		objectMap["name"] = ag.Name
	}
	if ag.Type != nil {
		objectMap["type"] = ag.Type
	}
	if ag.Location != nil {
		objectMap["location"] = ag.Location
	}
	if ag.Tags != nil {
		objectMap["tags"] = ag.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGateway struct.
func (ag *ApplicationGateway) 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 {
				var applicationGatewayPropertiesFormat ApplicationGatewayPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayPropertiesFormat)
				if err != nil {
					return err
				}
				ag.ApplicationGatewayPropertiesFormat = &applicationGatewayPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				ag.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ag.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ag.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ag.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				ag.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				ag.Tags = tags
			}
		}
	}

	return nil
}

// ApplicationGatewayAuthenticationCertificate authentication certificates of an application gateway.
type ApplicationGatewayAuthenticationCertificate struct {
	*ApplicationGatewayAuthenticationCertificatePropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayAuthenticationCertificate.
func (agac ApplicationGatewayAuthenticationCertificate) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agac.ApplicationGatewayAuthenticationCertificatePropertiesFormat != nil {
		objectMap["properties"] = agac.ApplicationGatewayAuthenticationCertificatePropertiesFormat
	}
	if agac.Name != nil {
		objectMap["name"] = agac.Name
	}
	if agac.Etag != nil {
		objectMap["etag"] = agac.Etag
	}
	if agac.Type != nil {
		objectMap["type"] = agac.Type
	}
	if agac.ID != nil {
		objectMap["id"] = agac.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayAuthenticationCertificate struct.
func (agac *ApplicationGatewayAuthenticationCertificate) 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 {
				var applicationGatewayAuthenticationCertificatePropertiesFormat ApplicationGatewayAuthenticationCertificatePropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayAuthenticationCertificatePropertiesFormat)
				if err != nil {
					return err
				}
				agac.ApplicationGatewayAuthenticationCertificatePropertiesFormat = &applicationGatewayAuthenticationCertificatePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agac.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agac.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agac.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agac.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayAuthenticationCertificatePropertiesFormat authentication certificates properties of an
// application gateway.
type ApplicationGatewayAuthenticationCertificatePropertiesFormat struct {
	// Data - Certificate public data.
	Data *string `json:"data,omitempty"`
	// ProvisioningState - Provisioning state of the authentication certificate resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayAvailableSslOptions response for ApplicationGatewayAvailableSslOptions API service
// call.
type ApplicationGatewayAvailableSslOptions struct {
	autorest.Response                                      `json:"-"`
	*ApplicationGatewayAvailableSslOptionsPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayAvailableSslOptions.
func (agaso ApplicationGatewayAvailableSslOptions) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agaso.ApplicationGatewayAvailableSslOptionsPropertiesFormat != nil {
		objectMap["properties"] = agaso.ApplicationGatewayAvailableSslOptionsPropertiesFormat
	}
	if agaso.ID != nil {
		objectMap["id"] = agaso.ID
	}
	if agaso.Name != nil {
		objectMap["name"] = agaso.Name
	}
	if agaso.Type != nil {
		objectMap["type"] = agaso.Type
	}
	if agaso.Location != nil {
		objectMap["location"] = agaso.Location
	}
	if agaso.Tags != nil {
		objectMap["tags"] = agaso.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayAvailableSslOptions struct.
func (agaso *ApplicationGatewayAvailableSslOptions) 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 {
				var applicationGatewayAvailableSslOptionsPropertiesFormat ApplicationGatewayAvailableSslOptionsPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayAvailableSslOptionsPropertiesFormat)
				if err != nil {
					return err
				}
				agaso.ApplicationGatewayAvailableSslOptionsPropertiesFormat = &applicationGatewayAvailableSslOptionsPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agaso.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agaso.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agaso.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				agaso.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				agaso.Tags = tags
			}
		}
	}

	return nil
}

// ApplicationGatewayAvailableSslOptionsPropertiesFormat properties of
// ApplicationGatewayAvailableSslOptions
type ApplicationGatewayAvailableSslOptionsPropertiesFormat struct {
	// PredefinedPolicies - List of available Ssl predefined policy.
	PredefinedPolicies *[]SubResource `json:"predefinedPolicies,omitempty"`
	// DefaultPolicy - Name of the Ssl predefined policy applied by default to application gateway. Possible values include: 'AppGwSslPolicy20150501', 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
	DefaultPolicy ApplicationGatewaySslPolicyName `json:"defaultPolicy,omitempty"`
	// AvailableCipherSuites - List of available Ssl cipher suites.
	AvailableCipherSuites *[]ApplicationGatewaySslCipherSuite `json:"availableCipherSuites,omitempty"`
	// AvailableProtocols - List of available Ssl protocols.
	AvailableProtocols *[]ApplicationGatewaySslProtocol `json:"availableProtocols,omitempty"`
}

// ApplicationGatewayAvailableSslPredefinedPolicies response for ApplicationGatewayAvailableSslOptions API
// service call.
type ApplicationGatewayAvailableSslPredefinedPolicies struct {
	autorest.Response `json:"-"`
	// Value - List of available Ssl predefined policy.
	Value *[]ApplicationGatewaySslPredefinedPolicy `json:"value,omitempty"`
	// NextLink - URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ApplicationGatewayAvailableSslPredefinedPoliciesIterator provides access to a complete listing of
// ApplicationGatewaySslPredefinedPolicy values.
type ApplicationGatewayAvailableSslPredefinedPoliciesIterator struct {
	i    int
	page ApplicationGatewayAvailableSslPredefinedPoliciesPage
}

// 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 *ApplicationGatewayAvailableSslPredefinedPoliciesIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationGatewayAvailableSslPredefinedPoliciesIterator.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 *ApplicationGatewayAvailableSslPredefinedPoliciesIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ApplicationGatewayAvailableSslPredefinedPoliciesIterator) 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 ApplicationGatewayAvailableSslPredefinedPoliciesIterator) Response() ApplicationGatewayAvailableSslPredefinedPolicies {
	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 ApplicationGatewayAvailableSslPredefinedPoliciesIterator) Value() ApplicationGatewaySslPredefinedPolicy {
	if !iter.page.NotDone() {
		return ApplicationGatewaySslPredefinedPolicy{}
	}
	return iter.page.Values()[iter.i]
}

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

// applicationGatewayAvailableSslPredefinedPoliciesPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (agaspp ApplicationGatewayAvailableSslPredefinedPolicies) applicationGatewayAvailableSslPredefinedPoliciesPreparer(ctx context.Context) (*http.Request, error) {
	if agaspp.NextLink == nil || len(to.String(agaspp.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(agaspp.NextLink)))
}

// ApplicationGatewayAvailableSslPredefinedPoliciesPage contains a page of
// ApplicationGatewaySslPredefinedPolicy values.
type ApplicationGatewayAvailableSslPredefinedPoliciesPage struct {
	fn     func(context.Context, ApplicationGatewayAvailableSslPredefinedPolicies) (ApplicationGatewayAvailableSslPredefinedPolicies, error)
	agaspp ApplicationGatewayAvailableSslPredefinedPolicies
}

// 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 *ApplicationGatewayAvailableSslPredefinedPoliciesPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationGatewayAvailableSslPredefinedPoliciesPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.agaspp)
	if err != nil {
		return err
	}
	page.agaspp = next
	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 *ApplicationGatewayAvailableSslPredefinedPoliciesPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ApplicationGatewayAvailableSslPredefinedPoliciesPage) Response() ApplicationGatewayAvailableSslPredefinedPolicies {
	return page.agaspp
}

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

// ApplicationGatewayAvailableWafRuleSetsResult response for ApplicationGatewayAvailableWafRuleSets API
// service call.
type ApplicationGatewayAvailableWafRuleSetsResult struct {
	autorest.Response `json:"-"`
	// Value - The list of application gateway rule sets.
	Value *[]ApplicationGatewayFirewallRuleSet `json:"value,omitempty"`
}

// ApplicationGatewayBackendAddress backend address of an application gateway.
type ApplicationGatewayBackendAddress struct {
	// Fqdn - Fully qualified domain name (FQDN).
	Fqdn *string `json:"fqdn,omitempty"`
	// IPAddress - IP address
	IPAddress *string `json:"ipAddress,omitempty"`
}

// ApplicationGatewayBackendAddressPool backend Address Pool of an application gateway.
type ApplicationGatewayBackendAddressPool struct {
	*ApplicationGatewayBackendAddressPoolPropertiesFormat `json:"properties,omitempty"`
	// Name - Resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayBackendAddressPool.
func (agbap ApplicationGatewayBackendAddressPool) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agbap.ApplicationGatewayBackendAddressPoolPropertiesFormat != nil {
		objectMap["properties"] = agbap.ApplicationGatewayBackendAddressPoolPropertiesFormat
	}
	if agbap.Name != nil {
		objectMap["name"] = agbap.Name
	}
	if agbap.Etag != nil {
		objectMap["etag"] = agbap.Etag
	}
	if agbap.Type != nil {
		objectMap["type"] = agbap.Type
	}
	if agbap.ID != nil {
		objectMap["id"] = agbap.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayBackendAddressPool struct.
func (agbap *ApplicationGatewayBackendAddressPool) 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 {
				var applicationGatewayBackendAddressPoolPropertiesFormat ApplicationGatewayBackendAddressPoolPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayBackendAddressPoolPropertiesFormat)
				if err != nil {
					return err
				}
				agbap.ApplicationGatewayBackendAddressPoolPropertiesFormat = &applicationGatewayBackendAddressPoolPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agbap.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agbap.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agbap.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agbap.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayBackendAddressPoolPropertiesFormat properties of Backend Address Pool of an
// application gateway.
type ApplicationGatewayBackendAddressPoolPropertiesFormat struct {
	// BackendIPConfigurations - Collection of references to IPs defined in network interfaces.
	BackendIPConfigurations *[]InterfaceIPConfiguration `json:"backendIPConfigurations,omitempty"`
	// BackendAddresses - Backend addresses
	BackendAddresses *[]ApplicationGatewayBackendAddress `json:"backendAddresses,omitempty"`
	// ProvisioningState - Provisioning state of the backend address pool resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayBackendHealth list of ApplicationGatewayBackendHealthPool resources.
type ApplicationGatewayBackendHealth struct {
	autorest.Response   `json:"-"`
	BackendAddressPools *[]ApplicationGatewayBackendHealthPool `json:"backendAddressPools,omitempty"`
}

// ApplicationGatewayBackendHealthHTTPSettings application gateway BackendHealthHttp settings.
type ApplicationGatewayBackendHealthHTTPSettings struct {
	// BackendHTTPSettings - Reference of an ApplicationGatewayBackendHttpSettings resource.
	BackendHTTPSettings *ApplicationGatewayBackendHTTPSettings `json:"backendHttpSettings,omitempty"`
	// Servers - List of ApplicationGatewayBackendHealthServer resources.
	Servers *[]ApplicationGatewayBackendHealthServer `json:"servers,omitempty"`
}

// ApplicationGatewayBackendHealthPool application gateway BackendHealth pool.
type ApplicationGatewayBackendHealthPool struct {
	// BackendAddressPool - Reference of an ApplicationGatewayBackendAddressPool resource.
	BackendAddressPool *ApplicationGatewayBackendAddressPool `json:"backendAddressPool,omitempty"`
	// BackendHTTPSettingsCollection - List of ApplicationGatewayBackendHealthHttpSettings resources.
	BackendHTTPSettingsCollection *[]ApplicationGatewayBackendHealthHTTPSettings `json:"backendHttpSettingsCollection,omitempty"`
}

// ApplicationGatewayBackendHealthServer application gateway backendhealth http settings.
type ApplicationGatewayBackendHealthServer struct {
	// Address - IP address or FQDN of backend server.
	Address *string `json:"address,omitempty"`
	// IPConfiguration - Reference of IP configuration of backend server.
	IPConfiguration *InterfaceIPConfiguration `json:"ipConfiguration,omitempty"`
	// Health - Health of backend server. Possible values include: 'Unknown', 'Up', 'Down', 'Partial', 'Draining'
	Health ApplicationGatewayBackendHealthServerHealth `json:"health,omitempty"`
}

// ApplicationGatewayBackendHTTPSettings backend address pool settings of an application gateway.
type ApplicationGatewayBackendHTTPSettings struct {
	*ApplicationGatewayBackendHTTPSettingsPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayBackendHTTPSettings.
func (agbhs ApplicationGatewayBackendHTTPSettings) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agbhs.ApplicationGatewayBackendHTTPSettingsPropertiesFormat != nil {
		objectMap["properties"] = agbhs.ApplicationGatewayBackendHTTPSettingsPropertiesFormat
	}
	if agbhs.Name != nil {
		objectMap["name"] = agbhs.Name
	}
	if agbhs.Etag != nil {
		objectMap["etag"] = agbhs.Etag
	}
	if agbhs.Type != nil {
		objectMap["type"] = agbhs.Type
	}
	if agbhs.ID != nil {
		objectMap["id"] = agbhs.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayBackendHTTPSettings struct.
func (agbhs *ApplicationGatewayBackendHTTPSettings) 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 {
				var applicationGatewayBackendHTTPSettingsPropertiesFormat ApplicationGatewayBackendHTTPSettingsPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayBackendHTTPSettingsPropertiesFormat)
				if err != nil {
					return err
				}
				agbhs.ApplicationGatewayBackendHTTPSettingsPropertiesFormat = &applicationGatewayBackendHTTPSettingsPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agbhs.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agbhs.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agbhs.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agbhs.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayBackendHTTPSettingsPropertiesFormat properties of Backend address pool settings of an
// application gateway.
type ApplicationGatewayBackendHTTPSettingsPropertiesFormat struct {
	// Port - Port
	Port *int32 `json:"port,omitempty"`
	// Protocol - Protocol. Possible values include: 'HTTP', 'HTTPS'
	Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"`
	// CookieBasedAffinity - Cookie based affinity. Possible values include: 'Enabled', 'Disabled'
	CookieBasedAffinity ApplicationGatewayCookieBasedAffinity `json:"cookieBasedAffinity,omitempty"`
	// RequestTimeout - Request timeout in seconds. Application Gateway will fail the request if response is not received within RequestTimeout. Acceptable values are from 1 second to 86400 seconds.
	RequestTimeout *int32 `json:"requestTimeout,omitempty"`
	// Probe - Probe resource of an application gateway.
	Probe *SubResource `json:"probe,omitempty"`
	// AuthenticationCertificates - Array of references to application gateway authentication certificates.
	AuthenticationCertificates *[]SubResource `json:"authenticationCertificates,omitempty"`
	// ConnectionDraining - Connection draining of the backend http settings resource.
	ConnectionDraining *ApplicationGatewayConnectionDraining `json:"connectionDraining,omitempty"`
	// HostName - Host header to be sent to the backend servers.
	HostName *string `json:"hostName,omitempty"`
	// PickHostNameFromBackendAddress - Whether to pick host header should be picked from the host name of the backend server. Default value is false.
	PickHostNameFromBackendAddress *bool `json:"pickHostNameFromBackendAddress,omitempty"`
	// AffinityCookieName - Cookie name to use for the affinity cookie.
	AffinityCookieName *string `json:"affinityCookieName,omitempty"`
	// ProbeEnabled - Whether the probe is enabled. Default value is false.
	ProbeEnabled *bool `json:"probeEnabled,omitempty"`
	// Path - Path which should be used as a prefix for all HTTP requests. Null means no path will be prefixed. Default value is null.
	Path *string `json:"path,omitempty"`
	// ProvisioningState - Provisioning state of the backend http settings resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayConnectionDraining connection draining allows open connections to a backend server to
// be active for a specified time after the backend server got removed from the configuration.
type ApplicationGatewayConnectionDraining struct {
	// Enabled - Whether connection draining is enabled or not.
	Enabled *bool `json:"enabled,omitempty"`
	// DrainTimeoutInSec - The number of seconds connection draining is active. Acceptable values are from 1 second to 3600 seconds.
	DrainTimeoutInSec *int32 `json:"drainTimeoutInSec,omitempty"`
}

// ApplicationGatewayFirewallDisabledRuleGroup allows to disable rules within a rule group or an entire
// rule group.
type ApplicationGatewayFirewallDisabledRuleGroup struct {
	// RuleGroupName - The name of the rule group that will be disabled.
	RuleGroupName *string `json:"ruleGroupName,omitempty"`
	// Rules - The list of rules that will be disabled. If null, all rules of the rule group will be disabled.
	Rules *[]int32 `json:"rules,omitempty"`
}

// ApplicationGatewayFirewallRule a web application firewall rule.
type ApplicationGatewayFirewallRule struct {
	// RuleID - The identifier of the web application firewall rule.
	RuleID *int32 `json:"ruleId,omitempty"`
	// Description - The description of the web application firewall rule.
	Description *string `json:"description,omitempty"`
}

// ApplicationGatewayFirewallRuleGroup a web application firewall rule group.
type ApplicationGatewayFirewallRuleGroup struct {
	// RuleGroupName - The name of the web application firewall rule group.
	RuleGroupName *string `json:"ruleGroupName,omitempty"`
	// Description - The description of the web application firewall rule group.
	Description *string `json:"description,omitempty"`
	// Rules - The rules of the web application firewall rule group.
	Rules *[]ApplicationGatewayFirewallRule `json:"rules,omitempty"`
}

// ApplicationGatewayFirewallRuleSet a web application firewall rule set.
type ApplicationGatewayFirewallRuleSet struct {
	*ApplicationGatewayFirewallRuleSetPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayFirewallRuleSet.
func (agfrs ApplicationGatewayFirewallRuleSet) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agfrs.ApplicationGatewayFirewallRuleSetPropertiesFormat != nil {
		objectMap["properties"] = agfrs.ApplicationGatewayFirewallRuleSetPropertiesFormat
	}
	if agfrs.ID != nil {
		objectMap["id"] = agfrs.ID
	}
	if agfrs.Name != nil {
		objectMap["name"] = agfrs.Name
	}
	if agfrs.Type != nil {
		objectMap["type"] = agfrs.Type
	}
	if agfrs.Location != nil {
		objectMap["location"] = agfrs.Location
	}
	if agfrs.Tags != nil {
		objectMap["tags"] = agfrs.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayFirewallRuleSet struct.
func (agfrs *ApplicationGatewayFirewallRuleSet) 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 {
				var applicationGatewayFirewallRuleSetPropertiesFormat ApplicationGatewayFirewallRuleSetPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayFirewallRuleSetPropertiesFormat)
				if err != nil {
					return err
				}
				agfrs.ApplicationGatewayFirewallRuleSetPropertiesFormat = &applicationGatewayFirewallRuleSetPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agfrs.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agfrs.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agfrs.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				agfrs.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				agfrs.Tags = tags
			}
		}
	}

	return nil
}

// ApplicationGatewayFirewallRuleSetPropertiesFormat properties of the web application firewall rule set.
type ApplicationGatewayFirewallRuleSetPropertiesFormat struct {
	// ProvisioningState - The provisioning state of the web application firewall rule set.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// RuleSetType - The type of the web application firewall rule set.
	RuleSetType *string `json:"ruleSetType,omitempty"`
	// RuleSetVersion - The version of the web application firewall rule set type.
	RuleSetVersion *string `json:"ruleSetVersion,omitempty"`
	// RuleGroups - The rule groups of the web application firewall rule set.
	RuleGroups *[]ApplicationGatewayFirewallRuleGroup `json:"ruleGroups,omitempty"`
}

// ApplicationGatewayFrontendIPConfiguration frontend IP configuration of an application gateway.
type ApplicationGatewayFrontendIPConfiguration struct {
	*ApplicationGatewayFrontendIPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayFrontendIPConfiguration.
func (agfic ApplicationGatewayFrontendIPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agfic.ApplicationGatewayFrontendIPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = agfic.ApplicationGatewayFrontendIPConfigurationPropertiesFormat
	}
	if agfic.Name != nil {
		objectMap["name"] = agfic.Name
	}
	if agfic.Etag != nil {
		objectMap["etag"] = agfic.Etag
	}
	if agfic.Type != nil {
		objectMap["type"] = agfic.Type
	}
	if agfic.ID != nil {
		objectMap["id"] = agfic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayFrontendIPConfiguration struct.
func (agfic *ApplicationGatewayFrontendIPConfiguration) 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 {
				var applicationGatewayFrontendIPConfigurationPropertiesFormat ApplicationGatewayFrontendIPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayFrontendIPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				agfic.ApplicationGatewayFrontendIPConfigurationPropertiesFormat = &applicationGatewayFrontendIPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agfic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agfic.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agfic.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agfic.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayFrontendIPConfigurationPropertiesFormat properties of Frontend IP configuration of an
// application gateway.
type ApplicationGatewayFrontendIPConfigurationPropertiesFormat struct {
	// PrivateIPAddress - PrivateIPAddress of the network interface IP Configuration.
	PrivateIPAddress *string `json:"privateIPAddress,omitempty"`
	// PrivateIPAllocationMethod - PrivateIP allocation method. Possible values include: 'Static', 'Dynamic'
	PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"`
	// Subnet - Reference of the subnet resource.
	Subnet *SubResource `json:"subnet,omitempty"`
	// PublicIPAddress - Reference of the PublicIP resource.
	PublicIPAddress *SubResource `json:"publicIPAddress,omitempty"`
	// ProvisioningState - Provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayFrontendPort frontend port of an application gateway.
type ApplicationGatewayFrontendPort struct {
	*ApplicationGatewayFrontendPortPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayFrontendPort.
func (agfp ApplicationGatewayFrontendPort) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agfp.ApplicationGatewayFrontendPortPropertiesFormat != nil {
		objectMap["properties"] = agfp.ApplicationGatewayFrontendPortPropertiesFormat
	}
	if agfp.Name != nil {
		objectMap["name"] = agfp.Name
	}
	if agfp.Etag != nil {
		objectMap["etag"] = agfp.Etag
	}
	if agfp.Type != nil {
		objectMap["type"] = agfp.Type
	}
	if agfp.ID != nil {
		objectMap["id"] = agfp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayFrontendPort struct.
func (agfp *ApplicationGatewayFrontendPort) 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 {
				var applicationGatewayFrontendPortPropertiesFormat ApplicationGatewayFrontendPortPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayFrontendPortPropertiesFormat)
				if err != nil {
					return err
				}
				agfp.ApplicationGatewayFrontendPortPropertiesFormat = &applicationGatewayFrontendPortPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agfp.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agfp.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agfp.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agfp.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayFrontendPortPropertiesFormat properties of Frontend port of an application gateway.
type ApplicationGatewayFrontendPortPropertiesFormat struct {
	// Port - Frontend port
	Port *int32 `json:"port,omitempty"`
	// ProvisioningState - Provisioning state of the frontend port resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayHTTPListener http listener of an application gateway.
type ApplicationGatewayHTTPListener struct {
	*ApplicationGatewayHTTPListenerPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayHTTPListener.
func (aghl ApplicationGatewayHTTPListener) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if aghl.ApplicationGatewayHTTPListenerPropertiesFormat != nil {
		objectMap["properties"] = aghl.ApplicationGatewayHTTPListenerPropertiesFormat
	}
	if aghl.Name != nil {
		objectMap["name"] = aghl.Name
	}
	if aghl.Etag != nil {
		objectMap["etag"] = aghl.Etag
	}
	if aghl.Type != nil {
		objectMap["type"] = aghl.Type
	}
	if aghl.ID != nil {
		objectMap["id"] = aghl.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayHTTPListener struct.
func (aghl *ApplicationGatewayHTTPListener) 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 {
				var applicationGatewayHTTPListenerPropertiesFormat ApplicationGatewayHTTPListenerPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayHTTPListenerPropertiesFormat)
				if err != nil {
					return err
				}
				aghl.ApplicationGatewayHTTPListenerPropertiesFormat = &applicationGatewayHTTPListenerPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				aghl.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				aghl.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				aghl.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				aghl.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayHTTPListenerPropertiesFormat properties of HTTP listener of an application gateway.
type ApplicationGatewayHTTPListenerPropertiesFormat struct {
	// FrontendIPConfiguration - Frontend IP configuration resource of an application gateway.
	FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"`
	// FrontendPort - Frontend port resource of an application gateway.
	FrontendPort *SubResource `json:"frontendPort,omitempty"`
	// Protocol - Protocol. Possible values include: 'HTTP', 'HTTPS'
	Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"`
	// HostName - Host name of HTTP listener.
	HostName *string `json:"hostName,omitempty"`
	// SslCertificate - SSL certificate resource of an application gateway.
	SslCertificate *SubResource `json:"sslCertificate,omitempty"`
	// RequireServerNameIndication - Applicable only if protocol is https. Enables SNI for multi-hosting.
	RequireServerNameIndication *bool `json:"requireServerNameIndication,omitempty"`
	// ProvisioningState - Provisioning state of the HTTP listener resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayIPConfiguration IP configuration of an application gateway. Currently 1 public and 1
// private IP configuration is allowed.
type ApplicationGatewayIPConfiguration struct {
	*ApplicationGatewayIPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayIPConfiguration.
func (agic ApplicationGatewayIPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agic.ApplicationGatewayIPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = agic.ApplicationGatewayIPConfigurationPropertiesFormat
	}
	if agic.Name != nil {
		objectMap["name"] = agic.Name
	}
	if agic.Etag != nil {
		objectMap["etag"] = agic.Etag
	}
	if agic.Type != nil {
		objectMap["type"] = agic.Type
	}
	if agic.ID != nil {
		objectMap["id"] = agic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayIPConfiguration struct.
func (agic *ApplicationGatewayIPConfiguration) 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 {
				var applicationGatewayIPConfigurationPropertiesFormat ApplicationGatewayIPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayIPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				agic.ApplicationGatewayIPConfigurationPropertiesFormat = &applicationGatewayIPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agic.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agic.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agic.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayIPConfigurationPropertiesFormat properties of IP configuration of an application
// gateway.
type ApplicationGatewayIPConfigurationPropertiesFormat struct {
	// Subnet - Reference of the subnet resource. A subnet from where application gateway gets its private address.
	Subnet *SubResource `json:"subnet,omitempty"`
	// ProvisioningState - Provisioning state of the application gateway subnet resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayListResult response for ListApplicationGateways API service call.
type ApplicationGatewayListResult struct {
	autorest.Response `json:"-"`
	// Value - List of an application gateways in a resource group.
	Value *[]ApplicationGateway `json:"value,omitempty"`
	// NextLink - URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ApplicationGatewayListResultIterator provides access to a complete listing of ApplicationGateway values.
type ApplicationGatewayListResultIterator struct {
	i    int
	page ApplicationGatewayListResultPage
}

// 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 *ApplicationGatewayListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationGatewayListResultIterator.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 *ApplicationGatewayListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ApplicationGatewayListResultIterator) 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 ApplicationGatewayListResultIterator) Response() ApplicationGatewayListResult {
	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 ApplicationGatewayListResultIterator) Value() ApplicationGateway {
	if !iter.page.NotDone() {
		return ApplicationGateway{}
	}
	return iter.page.Values()[iter.i]
}

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

// applicationGatewayListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (aglr ApplicationGatewayListResult) applicationGatewayListResultPreparer(ctx context.Context) (*http.Request, error) {
	if aglr.NextLink == nil || len(to.String(aglr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(aglr.NextLink)))
}

// ApplicationGatewayListResultPage contains a page of ApplicationGateway values.
type ApplicationGatewayListResultPage struct {
	fn   func(context.Context, ApplicationGatewayListResult) (ApplicationGatewayListResult, error)
	aglr ApplicationGatewayListResult
}

// 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 *ApplicationGatewayListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationGatewayListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.aglr)
	if err != nil {
		return err
	}
	page.aglr = next
	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 *ApplicationGatewayListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ApplicationGatewayListResultPage) Response() ApplicationGatewayListResult {
	return page.aglr
}

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

// ApplicationGatewayPathRule path rule of URL path map of an application gateway.
type ApplicationGatewayPathRule struct {
	*ApplicationGatewayPathRulePropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayPathRule.
func (agpr ApplicationGatewayPathRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agpr.ApplicationGatewayPathRulePropertiesFormat != nil {
		objectMap["properties"] = agpr.ApplicationGatewayPathRulePropertiesFormat
	}
	if agpr.Name != nil {
		objectMap["name"] = agpr.Name
	}
	if agpr.Etag != nil {
		objectMap["etag"] = agpr.Etag
	}
	if agpr.Type != nil {
		objectMap["type"] = agpr.Type
	}
	if agpr.ID != nil {
		objectMap["id"] = agpr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayPathRule struct.
func (agpr *ApplicationGatewayPathRule) 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 {
				var applicationGatewayPathRulePropertiesFormat ApplicationGatewayPathRulePropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayPathRulePropertiesFormat)
				if err != nil {
					return err
				}
				agpr.ApplicationGatewayPathRulePropertiesFormat = &applicationGatewayPathRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agpr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agpr.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agpr.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agpr.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayPathRulePropertiesFormat properties of path rule of an application gateway.
type ApplicationGatewayPathRulePropertiesFormat struct {
	// Paths - Path rules of URL path map.
	Paths *[]string `json:"paths,omitempty"`
	// BackendAddressPool - Backend address pool resource of URL path map path rule.
	BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"`
	// BackendHTTPSettings - Backend http settings resource of URL path map path rule.
	BackendHTTPSettings *SubResource `json:"backendHttpSettings,omitempty"`
	// RedirectConfiguration - Redirect configuration resource of URL path map path rule.
	RedirectConfiguration *SubResource `json:"redirectConfiguration,omitempty"`
	// ProvisioningState - Path rule of URL path map resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayProbe probe of the application gateway.
type ApplicationGatewayProbe struct {
	*ApplicationGatewayProbePropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayProbe.
func (agp ApplicationGatewayProbe) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agp.ApplicationGatewayProbePropertiesFormat != nil {
		objectMap["properties"] = agp.ApplicationGatewayProbePropertiesFormat
	}
	if agp.Name != nil {
		objectMap["name"] = agp.Name
	}
	if agp.Etag != nil {
		objectMap["etag"] = agp.Etag
	}
	if agp.Type != nil {
		objectMap["type"] = agp.Type
	}
	if agp.ID != nil {
		objectMap["id"] = agp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayProbe struct.
func (agp *ApplicationGatewayProbe) 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 {
				var applicationGatewayProbePropertiesFormat ApplicationGatewayProbePropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayProbePropertiesFormat)
				if err != nil {
					return err
				}
				agp.ApplicationGatewayProbePropertiesFormat = &applicationGatewayProbePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agp.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agp.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agp.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agp.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayProbeHealthResponseMatch application gateway probe health response match
type ApplicationGatewayProbeHealthResponseMatch struct {
	// Body - Body that must be contained in the health response. Default value is empty.
	Body *string `json:"body,omitempty"`
	// StatusCodes - Allowed ranges of healthy status codes. Default range of healthy status codes is 200-399.
	StatusCodes *[]string `json:"statusCodes,omitempty"`
}

// ApplicationGatewayProbePropertiesFormat properties of probe of an application gateway.
type ApplicationGatewayProbePropertiesFormat struct {
	// Protocol - Protocol. Possible values include: 'HTTP', 'HTTPS'
	Protocol ApplicationGatewayProtocol `json:"protocol,omitempty"`
	// Host - Host name to send the probe to.
	Host *string `json:"host,omitempty"`
	// Path - Relative path of probe. Valid path starts from '/'. Probe is sent to <Protocol>://<host>:<port><path>
	Path *string `json:"path,omitempty"`
	// Interval - The probing interval in seconds. This is the time interval between two consecutive probes. Acceptable values are from 1 second to 86400 seconds.
	Interval *int32 `json:"interval,omitempty"`
	// Timeout - the probe timeout in seconds. Probe marked as failed if valid response is not received with this timeout period. Acceptable values are from 1 second to 86400 seconds.
	Timeout *int32 `json:"timeout,omitempty"`
	// UnhealthyThreshold - The probe retry count. Backend server is marked down after consecutive probe failure count reaches UnhealthyThreshold. Acceptable values are from 1 second to 20.
	UnhealthyThreshold *int32 `json:"unhealthyThreshold,omitempty"`
	// PickHostNameFromBackendHTTPSettings - Whether the host header should be picked from the backend http settings. Default value is false.
	PickHostNameFromBackendHTTPSettings *bool `json:"pickHostNameFromBackendHttpSettings,omitempty"`
	// MinServers - Minimum number of servers that are always marked healthy. Default value is 0.
	MinServers *int32 `json:"minServers,omitempty"`
	// Match - Criterion for classifying a healthy probe response.
	Match *ApplicationGatewayProbeHealthResponseMatch `json:"match,omitempty"`
	// ProvisioningState - Provisioning state of the backend http settings resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayPropertiesFormat properties of the application gateway.
type ApplicationGatewayPropertiesFormat struct {
	// Sku - SKU of the application gateway resource.
	Sku *ApplicationGatewaySku `json:"sku,omitempty"`
	// SslPolicy - SSL policy of the application gateway resource.
	SslPolicy *ApplicationGatewaySslPolicy `json:"sslPolicy,omitempty"`
	// OperationalState - Operational state of the application gateway resource. Possible values include: 'Stopped', 'Starting', 'Running', 'Stopping'
	OperationalState ApplicationGatewayOperationalState `json:"operationalState,omitempty"`
	// GatewayIPConfigurations - Subnets of application the gateway resource.
	GatewayIPConfigurations *[]ApplicationGatewayIPConfiguration `json:"gatewayIPConfigurations,omitempty"`
	// AuthenticationCertificates - Authentication certificates of the application gateway resource.
	AuthenticationCertificates *[]ApplicationGatewayAuthenticationCertificate `json:"authenticationCertificates,omitempty"`
	// SslCertificates - SSL certificates of the application gateway resource.
	SslCertificates *[]ApplicationGatewaySslCertificate `json:"sslCertificates,omitempty"`
	// FrontendIPConfigurations - Frontend IP addresses of the application gateway resource.
	FrontendIPConfigurations *[]ApplicationGatewayFrontendIPConfiguration `json:"frontendIPConfigurations,omitempty"`
	// FrontendPorts - Frontend ports of the application gateway resource.
	FrontendPorts *[]ApplicationGatewayFrontendPort `json:"frontendPorts,omitempty"`
	// Probes - Probes of the application gateway resource.
	Probes *[]ApplicationGatewayProbe `json:"probes,omitempty"`
	// BackendAddressPools - Backend address pool of the application gateway resource.
	BackendAddressPools *[]ApplicationGatewayBackendAddressPool `json:"backendAddressPools,omitempty"`
	// BackendHTTPSettingsCollection - Backend http settings of the application gateway resource.
	BackendHTTPSettingsCollection *[]ApplicationGatewayBackendHTTPSettings `json:"backendHttpSettingsCollection,omitempty"`
	// HTTPListeners - Http listeners of the application gateway resource.
	HTTPListeners *[]ApplicationGatewayHTTPListener `json:"httpListeners,omitempty"`
	// URLPathMaps - URL path map of the application gateway resource.
	URLPathMaps *[]ApplicationGatewayURLPathMap `json:"urlPathMaps,omitempty"`
	// RequestRoutingRules - Request routing rules of the application gateway resource.
	RequestRoutingRules *[]ApplicationGatewayRequestRoutingRule `json:"requestRoutingRules,omitempty"`
	// RedirectConfigurations - Redirect configurations of the application gateway resource.
	RedirectConfigurations *[]ApplicationGatewayRedirectConfiguration `json:"redirectConfigurations,omitempty"`
	// WebApplicationFirewallConfiguration - Web application firewall configuration.
	WebApplicationFirewallConfiguration *ApplicationGatewayWebApplicationFirewallConfiguration `json:"webApplicationFirewallConfiguration,omitempty"`
	// ResourceGUID - Resource GUID property of the application gateway resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - Provisioning state of the application gateway resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayRedirectConfiguration redirect configuration of an application gateway.
type ApplicationGatewayRedirectConfiguration struct {
	*ApplicationGatewayRedirectConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayRedirectConfiguration.
func (agrc ApplicationGatewayRedirectConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agrc.ApplicationGatewayRedirectConfigurationPropertiesFormat != nil {
		objectMap["properties"] = agrc.ApplicationGatewayRedirectConfigurationPropertiesFormat
	}
	if agrc.Name != nil {
		objectMap["name"] = agrc.Name
	}
	if agrc.Etag != nil {
		objectMap["etag"] = agrc.Etag
	}
	if agrc.Type != nil {
		objectMap["type"] = agrc.Type
	}
	if agrc.ID != nil {
		objectMap["id"] = agrc.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayRedirectConfiguration struct.
func (agrc *ApplicationGatewayRedirectConfiguration) 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 {
				var applicationGatewayRedirectConfigurationPropertiesFormat ApplicationGatewayRedirectConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayRedirectConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				agrc.ApplicationGatewayRedirectConfigurationPropertiesFormat = &applicationGatewayRedirectConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agrc.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agrc.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agrc.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agrc.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayRedirectConfigurationPropertiesFormat properties of redirect configuration of the
// application gateway.
type ApplicationGatewayRedirectConfigurationPropertiesFormat struct {
	// RedirectType - Supported http redirection types - Permanent, Temporary, Found, SeeOther. Possible values include: 'Permanent', 'Found', 'SeeOther', 'Temporary'
	RedirectType ApplicationGatewayRedirectType `json:"redirectType,omitempty"`
	// TargetListener - Reference to a listener to redirect the request to.
	TargetListener *SubResource `json:"targetListener,omitempty"`
	// TargetURL - Url to redirect the request to.
	TargetURL *string `json:"targetUrl,omitempty"`
	// IncludePath - Include path in the redirected url.
	IncludePath *bool `json:"includePath,omitempty"`
	// IncludeQueryString - Include query string in the redirected url.
	IncludeQueryString *bool `json:"includeQueryString,omitempty"`
	// RequestRoutingRules - Request routing specifying redirect configuration.
	RequestRoutingRules *[]SubResource `json:"requestRoutingRules,omitempty"`
	// URLPathMaps - Url path maps specifying default redirect configuration.
	URLPathMaps *[]SubResource `json:"urlPathMaps,omitempty"`
	// PathRules - Path rules specifying redirect configuration.
	PathRules *[]SubResource `json:"pathRules,omitempty"`
}

// ApplicationGatewayRequestRoutingRule request routing rule of an application gateway.
type ApplicationGatewayRequestRoutingRule struct {
	*ApplicationGatewayRequestRoutingRulePropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayRequestRoutingRule.
func (agrrr ApplicationGatewayRequestRoutingRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agrrr.ApplicationGatewayRequestRoutingRulePropertiesFormat != nil {
		objectMap["properties"] = agrrr.ApplicationGatewayRequestRoutingRulePropertiesFormat
	}
	if agrrr.Name != nil {
		objectMap["name"] = agrrr.Name
	}
	if agrrr.Etag != nil {
		objectMap["etag"] = agrrr.Etag
	}
	if agrrr.Type != nil {
		objectMap["type"] = agrrr.Type
	}
	if agrrr.ID != nil {
		objectMap["id"] = agrrr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayRequestRoutingRule struct.
func (agrrr *ApplicationGatewayRequestRoutingRule) 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 {
				var applicationGatewayRequestRoutingRulePropertiesFormat ApplicationGatewayRequestRoutingRulePropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayRequestRoutingRulePropertiesFormat)
				if err != nil {
					return err
				}
				agrrr.ApplicationGatewayRequestRoutingRulePropertiesFormat = &applicationGatewayRequestRoutingRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agrrr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agrrr.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agrrr.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agrrr.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayRequestRoutingRulePropertiesFormat properties of request routing rule of the
// application gateway.
type ApplicationGatewayRequestRoutingRulePropertiesFormat struct {
	// RuleType - Rule type. Possible values include: 'Basic', 'PathBasedRouting'
	RuleType ApplicationGatewayRequestRoutingRuleType `json:"ruleType,omitempty"`
	// BackendAddressPool - Backend address pool resource of the application gateway.
	BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"`
	// BackendHTTPSettings - Frontend port resource of the application gateway.
	BackendHTTPSettings *SubResource `json:"backendHttpSettings,omitempty"`
	// HTTPListener - Http listener resource of the application gateway.
	HTTPListener *SubResource `json:"httpListener,omitempty"`
	// URLPathMap - URL path map resource of the application gateway.
	URLPathMap *SubResource `json:"urlPathMap,omitempty"`
	// RedirectConfiguration - Redirect configuration resource of the application gateway.
	RedirectConfiguration *SubResource `json:"redirectConfiguration,omitempty"`
	// ProvisioningState - Provisioning state of the request routing rule resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewaysBackendHealthFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationGatewaysBackendHealthFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysBackendHealthFuture) Result(client ApplicationGatewaysClient) (agbh ApplicationGatewayBackendHealth, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysBackendHealthFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if agbh.Response.Response, err = future.GetResult(sender); err == nil && agbh.Response.Response.StatusCode != http.StatusNoContent {
		agbh, err = client.BackendHealthResponder(agbh.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysBackendHealthFuture", "Result", agbh.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplicationGatewaysCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationGatewaysCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysCreateOrUpdateFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ag.Response.Response, err = future.GetResult(sender); err == nil && ag.Response.Response.StatusCode != http.StatusNoContent {
		ag, err = client.CreateOrUpdateResponder(ag.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysCreateOrUpdateFuture", "Result", ag.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplicationGatewaysDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationGatewaysDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysDeleteFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ApplicationGatewaySku SKU of an application gateway
type ApplicationGatewaySku struct {
	// Name - Name of an application gateway SKU. Possible values include: 'StandardSmall', 'StandardMedium', 'StandardLarge', 'WAFMedium', 'WAFLarge'
	Name ApplicationGatewaySkuName `json:"name,omitempty"`
	// Tier - Tier of an application gateway. Possible values include: 'Standard', 'WAF'
	Tier ApplicationGatewayTier `json:"tier,omitempty"`
	// Capacity - Capacity (instance count) of an application gateway.
	Capacity *int32 `json:"capacity,omitempty"`
}

// ApplicationGatewaySslCertificate SSL certificates of an application gateway.
type ApplicationGatewaySslCertificate struct {
	*ApplicationGatewaySslCertificatePropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewaySslCertificate.
func (agsc ApplicationGatewaySslCertificate) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agsc.ApplicationGatewaySslCertificatePropertiesFormat != nil {
		objectMap["properties"] = agsc.ApplicationGatewaySslCertificatePropertiesFormat
	}
	if agsc.Name != nil {
		objectMap["name"] = agsc.Name
	}
	if agsc.Etag != nil {
		objectMap["etag"] = agsc.Etag
	}
	if agsc.Type != nil {
		objectMap["type"] = agsc.Type
	}
	if agsc.ID != nil {
		objectMap["id"] = agsc.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewaySslCertificate struct.
func (agsc *ApplicationGatewaySslCertificate) 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 {
				var applicationGatewaySslCertificatePropertiesFormat ApplicationGatewaySslCertificatePropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewaySslCertificatePropertiesFormat)
				if err != nil {
					return err
				}
				agsc.ApplicationGatewaySslCertificatePropertiesFormat = &applicationGatewaySslCertificatePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agsc.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agsc.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agsc.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agsc.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewaySslCertificatePropertiesFormat properties of SSL certificates of an application
// gateway.
type ApplicationGatewaySslCertificatePropertiesFormat struct {
	// Data - Base-64 encoded pfx certificate. Only applicable in PUT Request.
	Data *string `json:"data,omitempty"`
	// Password - Password for the pfx file specified in data. Only applicable in PUT request.
	Password *string `json:"password,omitempty"`
	// PublicCertData - Base-64 encoded Public cert data corresponding to pfx specified in data. Only applicable in GET request.
	PublicCertData *string `json:"publicCertData,omitempty"`
	// ProvisioningState - Provisioning state of the SSL certificate resource Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewaySslPolicy application Gateway Ssl policy.
type ApplicationGatewaySslPolicy struct {
	// DisabledSslProtocols - Ssl protocols to be disabled on application gateway.
	DisabledSslProtocols *[]ApplicationGatewaySslProtocol `json:"disabledSslProtocols,omitempty"`
	// PolicyType - Type of Ssl Policy. Possible values include: 'Predefined', 'Custom'
	PolicyType ApplicationGatewaySslPolicyType `json:"policyType,omitempty"`
	// PolicyName - Name of Ssl predefined policy. Possible values include: 'AppGwSslPolicy20150501', 'AppGwSslPolicy20170401', 'AppGwSslPolicy20170401S'
	PolicyName ApplicationGatewaySslPolicyName `json:"policyName,omitempty"`
	// CipherSuites - Ssl cipher suites to be enabled in the specified order to application gateway.
	CipherSuites *[]ApplicationGatewaySslCipherSuite `json:"cipherSuites,omitempty"`
	// MinProtocolVersion - Minimum version of Ssl protocol to be supported on application gateway. Possible values include: 'TLSv10', 'TLSv11', 'TLSv12'
	MinProtocolVersion ApplicationGatewaySslProtocol `json:"minProtocolVersion,omitempty"`
}

// ApplicationGatewaySslPredefinedPolicy an Ssl predefined policy
type ApplicationGatewaySslPredefinedPolicy struct {
	autorest.Response `json:"-"`
	// Name - Name of Ssl predefined policy.
	Name                                                   *string `json:"name,omitempty"`
	*ApplicationGatewaySslPredefinedPolicyPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewaySslPredefinedPolicy.
func (agspp ApplicationGatewaySslPredefinedPolicy) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agspp.Name != nil {
		objectMap["name"] = agspp.Name
	}
	if agspp.ApplicationGatewaySslPredefinedPolicyPropertiesFormat != nil {
		objectMap["properties"] = agspp.ApplicationGatewaySslPredefinedPolicyPropertiesFormat
	}
	if agspp.ID != nil {
		objectMap["id"] = agspp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewaySslPredefinedPolicy struct.
func (agspp *ApplicationGatewaySslPredefinedPolicy) 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 "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agspp.Name = &name
			}
		case "properties":
			if v != nil {
				var applicationGatewaySslPredefinedPolicyPropertiesFormat ApplicationGatewaySslPredefinedPolicyPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewaySslPredefinedPolicyPropertiesFormat)
				if err != nil {
					return err
				}
				agspp.ApplicationGatewaySslPredefinedPolicyPropertiesFormat = &applicationGatewaySslPredefinedPolicyPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agspp.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewaySslPredefinedPolicyPropertiesFormat properties of
// ApplicationGatewaySslPredefinedPolicy
type ApplicationGatewaySslPredefinedPolicyPropertiesFormat struct {
	// CipherSuites - Ssl cipher suites to be enabled in the specified order for application gateway.
	CipherSuites *[]ApplicationGatewaySslCipherSuite `json:"cipherSuites,omitempty"`
	// MinProtocolVersion - Minimum version of Ssl protocol to be supported on application gateway. Possible values include: 'TLSv10', 'TLSv11', 'TLSv12'
	MinProtocolVersion ApplicationGatewaySslProtocol `json:"minProtocolVersion,omitempty"`
}

// ApplicationGatewaysStartFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationGatewaysStartFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysStartFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStartFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStartFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ApplicationGatewaysStopFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type ApplicationGatewaysStopFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysStopFuture) Result(client ApplicationGatewaysClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysStopFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysStopFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ApplicationGatewaysUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationGatewaysUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationGatewaysUpdateTagsFuture) Result(client ApplicationGatewaysClient) (ag ApplicationGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationGatewaysUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ag.Response.Response, err = future.GetResult(sender); err == nil && ag.Response.Response.StatusCode != http.StatusNoContent {
		ag, err = client.UpdateTagsResponder(ag.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ApplicationGatewaysUpdateTagsFuture", "Result", ag.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplicationGatewayURLPathMap urlPathMaps give a url path to the backend mapping information for
// PathBasedRouting.
type ApplicationGatewayURLPathMap struct {
	*ApplicationGatewayURLPathMapPropertiesFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Type of the resource.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ApplicationGatewayURLPathMap.
func (agupm ApplicationGatewayURLPathMap) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if agupm.ApplicationGatewayURLPathMapPropertiesFormat != nil {
		objectMap["properties"] = agupm.ApplicationGatewayURLPathMapPropertiesFormat
	}
	if agupm.Name != nil {
		objectMap["name"] = agupm.Name
	}
	if agupm.Etag != nil {
		objectMap["etag"] = agupm.Etag
	}
	if agupm.Type != nil {
		objectMap["type"] = agupm.Type
	}
	if agupm.ID != nil {
		objectMap["id"] = agupm.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationGatewayURLPathMap struct.
func (agupm *ApplicationGatewayURLPathMap) 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 {
				var applicationGatewayURLPathMapPropertiesFormat ApplicationGatewayURLPathMapPropertiesFormat
				err = json.Unmarshal(*v, &applicationGatewayURLPathMapPropertiesFormat)
				if err != nil {
					return err
				}
				agupm.ApplicationGatewayURLPathMapPropertiesFormat = &applicationGatewayURLPathMapPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				agupm.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				agupm.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				agupm.Type = &typeVar
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				agupm.ID = &ID
			}
		}
	}

	return nil
}

// ApplicationGatewayURLPathMapPropertiesFormat properties of UrlPathMap of the application gateway.
type ApplicationGatewayURLPathMapPropertiesFormat struct {
	// DefaultBackendAddressPool - Default backend address pool resource of URL path map.
	DefaultBackendAddressPool *SubResource `json:"defaultBackendAddressPool,omitempty"`
	// DefaultBackendHTTPSettings - Default backend http settings resource of URL path map.
	DefaultBackendHTTPSettings *SubResource `json:"defaultBackendHttpSettings,omitempty"`
	// DefaultRedirectConfiguration - Default redirect configuration resource of URL path map.
	DefaultRedirectConfiguration *SubResource `json:"defaultRedirectConfiguration,omitempty"`
	// PathRules - Path rule of URL path map resource.
	PathRules *[]ApplicationGatewayPathRule `json:"pathRules,omitempty"`
	// ProvisioningState - Provisioning state of the backend http settings resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationGatewayWebApplicationFirewallConfiguration application gateway web application firewall
// configuration.
type ApplicationGatewayWebApplicationFirewallConfiguration struct {
	// Enabled - Whether the web application firewall is enabled or not.
	Enabled *bool `json:"enabled,omitempty"`
	// FirewallMode - Web application firewall mode. Possible values include: 'Detection', 'Prevention'
	FirewallMode ApplicationGatewayFirewallMode `json:"firewallMode,omitempty"`
	// RuleSetType - The type of the web application firewall rule set. Possible values are: 'OWASP'.
	RuleSetType *string `json:"ruleSetType,omitempty"`
	// RuleSetVersion - The version of the rule set type.
	RuleSetVersion *string `json:"ruleSetVersion,omitempty"`
	// DisabledRuleGroups - The disabled rule groups.
	DisabledRuleGroups *[]ApplicationGatewayFirewallDisabledRuleGroup `json:"disabledRuleGroups,omitempty"`
}

// ApplicationSecurityGroup an application security group in a resource group.
type ApplicationSecurityGroup struct {
	autorest.Response `json:"-"`
	// ApplicationSecurityGroupPropertiesFormat - Properties of the application security group.
	*ApplicationSecurityGroupPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ApplicationSecurityGroup.
func (asg ApplicationSecurityGroup) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if asg.ApplicationSecurityGroupPropertiesFormat != nil {
		objectMap["properties"] = asg.ApplicationSecurityGroupPropertiesFormat
	}
	if asg.Etag != nil {
		objectMap["etag"] = asg.Etag
	}
	if asg.ID != nil {
		objectMap["id"] = asg.ID
	}
	if asg.Name != nil {
		objectMap["name"] = asg.Name
	}
	if asg.Type != nil {
		objectMap["type"] = asg.Type
	}
	if asg.Location != nil {
		objectMap["location"] = asg.Location
	}
	if asg.Tags != nil {
		objectMap["tags"] = asg.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ApplicationSecurityGroup struct.
func (asg *ApplicationSecurityGroup) 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 {
				var applicationSecurityGroupPropertiesFormat ApplicationSecurityGroupPropertiesFormat
				err = json.Unmarshal(*v, &applicationSecurityGroupPropertiesFormat)
				if err != nil {
					return err
				}
				asg.ApplicationSecurityGroupPropertiesFormat = &applicationSecurityGroupPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				asg.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				asg.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				asg.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				asg.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				asg.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				asg.Tags = tags
			}
		}
	}

	return nil
}

// ApplicationSecurityGroupListResult a list of application security groups.
type ApplicationSecurityGroupListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of application security groups.
	Value *[]ApplicationSecurityGroup `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ApplicationSecurityGroupListResultIterator provides access to a complete listing of
// ApplicationSecurityGroup values.
type ApplicationSecurityGroupListResultIterator struct {
	i    int
	page ApplicationSecurityGroupListResultPage
}

// 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 *ApplicationSecurityGroupListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationSecurityGroupListResultIterator.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 *ApplicationSecurityGroupListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ApplicationSecurityGroupListResultIterator) 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 ApplicationSecurityGroupListResultIterator) Response() ApplicationSecurityGroupListResult {
	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 ApplicationSecurityGroupListResultIterator) Value() ApplicationSecurityGroup {
	if !iter.page.NotDone() {
		return ApplicationSecurityGroup{}
	}
	return iter.page.Values()[iter.i]
}

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

// applicationSecurityGroupListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (asglr ApplicationSecurityGroupListResult) applicationSecurityGroupListResultPreparer(ctx context.Context) (*http.Request, error) {
	if asglr.NextLink == nil || len(to.String(asglr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(asglr.NextLink)))
}

// ApplicationSecurityGroupListResultPage contains a page of ApplicationSecurityGroup values.
type ApplicationSecurityGroupListResultPage struct {
	fn    func(context.Context, ApplicationSecurityGroupListResult) (ApplicationSecurityGroupListResult, error)
	asglr ApplicationSecurityGroupListResult
}

// 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 *ApplicationSecurityGroupListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ApplicationSecurityGroupListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.asglr)
	if err != nil {
		return err
	}
	page.asglr = next
	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 *ApplicationSecurityGroupListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ApplicationSecurityGroupListResultPage) Response() ApplicationSecurityGroupListResult {
	return page.asglr
}

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

// ApplicationSecurityGroupPropertiesFormat application security group properties.
type ApplicationSecurityGroupPropertiesFormat struct {
	// ResourceGUID - The resource GUID property of the application security group resource. It uniquely identifies a resource, even if the user changes its name or migrate the resource across subscriptions or resource groups.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the application security group resource. Possible values are: 'Succeeded', 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// ApplicationSecurityGroupsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results
// of a long-running operation.
type ApplicationSecurityGroupsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationSecurityGroupsCreateOrUpdateFuture) Result(client ApplicationSecurityGroupsClient) (asg ApplicationSecurityGroup, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if asg.Response.Response, err = future.GetResult(sender); err == nil && asg.Response.Response.StatusCode != http.StatusNoContent {
		asg, err = client.CreateOrUpdateResponder(asg.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsCreateOrUpdateFuture", "Result", asg.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ApplicationSecurityGroupsDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ApplicationSecurityGroupsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ApplicationSecurityGroupsDeleteFuture) Result(client ApplicationSecurityGroupsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ApplicationSecurityGroupsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ApplicationSecurityGroupsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// AuthorizationListResult response for ListAuthorizations API service call retrieves all authorizations
// that belongs to an ExpressRouteCircuit.
type AuthorizationListResult struct {
	autorest.Response `json:"-"`
	// Value - The authorizations in an ExpressRoute Circuit.
	Value *[]ExpressRouteCircuitAuthorization `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// AuthorizationListResultIterator provides access to a complete listing of
// ExpressRouteCircuitAuthorization values.
type AuthorizationListResultIterator struct {
	i    int
	page AuthorizationListResultPage
}

// 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 *AuthorizationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/AuthorizationListResultIterator.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 *AuthorizationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter AuthorizationListResultIterator) 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 AuthorizationListResultIterator) Response() AuthorizationListResult {
	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 AuthorizationListResultIterator) Value() ExpressRouteCircuitAuthorization {
	if !iter.page.NotDone() {
		return ExpressRouteCircuitAuthorization{}
	}
	return iter.page.Values()[iter.i]
}

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

// authorizationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (alr AuthorizationListResult) authorizationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if alr.NextLink == nil || len(to.String(alr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(alr.NextLink)))
}

// AuthorizationListResultPage contains a page of ExpressRouteCircuitAuthorization values.
type AuthorizationListResultPage struct {
	fn  func(context.Context, AuthorizationListResult) (AuthorizationListResult, error)
	alr AuthorizationListResult
}

// 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 *AuthorizationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/AuthorizationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.alr)
	if err != nil {
		return err
	}
	page.alr = next
	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 *AuthorizationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page AuthorizationListResultPage) Response() AuthorizationListResult {
	return page.alr
}

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

// AuthorizationPropertiesFormat ...
type AuthorizationPropertiesFormat struct {
	// AuthorizationKey - The authorization key.
	AuthorizationKey *string `json:"authorizationKey,omitempty"`
	// AuthorizationUseStatus - AuthorizationUseStatus. Possible values are: 'Available' and 'InUse'. Possible values include: 'Available', 'InUse'
	AuthorizationUseStatus AuthorizationUseStatus `json:"authorizationUseStatus,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// Availability availability of the metric.
type Availability struct {
	// TimeGrain - The time grain of the availability.
	TimeGrain *string `json:"timeGrain,omitempty"`
	// Retention - The retention of the availability.
	Retention *string `json:"retention,omitempty"`
	// BlobDuration - Duration of the availability blob.
	BlobDuration *string `json:"blobDuration,omitempty"`
}

// AvailableProvidersList list of available countries with details.
type AvailableProvidersList struct {
	autorest.Response `json:"-"`
	// Countries - List of available countries.
	Countries *[]AvailableProvidersListCountry `json:"countries,omitempty"`
}

// AvailableProvidersListCity city or town details.
type AvailableProvidersListCity struct {
	// CityName - The city or town name.
	CityName *string `json:"cityName,omitempty"`
	// Providers - A list of Internet service providers.
	Providers *[]string `json:"providers,omitempty"`
}

// AvailableProvidersListCountry country details.
type AvailableProvidersListCountry struct {
	// CountryName - The country name.
	CountryName *string `json:"countryName,omitempty"`
	// Providers - A list of Internet service providers.
	Providers *[]string `json:"providers,omitempty"`
	// States - List of available states in the country.
	States *[]AvailableProvidersListState `json:"states,omitempty"`
}

// AvailableProvidersListParameters constraints that determine the list of available Internet service
// providers.
type AvailableProvidersListParameters struct {
	// AzureLocations - A list of Azure regions.
	AzureLocations *[]string `json:"azureLocations,omitempty"`
	// Country - The country for available providers list.
	Country *string `json:"country,omitempty"`
	// State - The state for available providers list.
	State *string `json:"state,omitempty"`
	// City - The city or town for available providers list.
	City *string `json:"city,omitempty"`
}

// AvailableProvidersListState state details.
type AvailableProvidersListState struct {
	// StateName - The state name.
	StateName *string `json:"stateName,omitempty"`
	// Providers - A list of Internet service providers.
	Providers *[]string `json:"providers,omitempty"`
	// Cities - List of available cities or towns in the state.
	Cities *[]AvailableProvidersListCity `json:"cities,omitempty"`
}

// AzureAsyncOperationResult the response body contains the status of the specified asynchronous operation,
// indicating whether it has succeeded, is in progress, or has failed. Note that this status is distinct
// from the HTTP status code returned for the Get Operation Status operation itself. If the asynchronous
// operation succeeded, the response body includes the HTTP status code for the successful request. If the
// asynchronous operation failed, the response body includes the HTTP status code for the failed request
// and error information regarding the failure.
type AzureAsyncOperationResult struct {
	// Status - Status of the Azure async operation. Possible values are: 'InProgress', 'Succeeded', and 'Failed'. Possible values include: 'InProgress', 'Succeeded', 'Failed'
	Status OperationStatus `json:"status,omitempty"`
	Error  *Error          `json:"error,omitempty"`
}

// AzureReachabilityReport azure reachability report details.
type AzureReachabilityReport struct {
	autorest.Response `json:"-"`
	// AggregationLevel - The aggregation level of Azure reachability report. Can be Country, State or City.
	AggregationLevel *string                          `json:"aggregationLevel,omitempty"`
	ProviderLocation *AzureReachabilityReportLocation `json:"providerLocation,omitempty"`
	// ReachabilityReport - List of Azure reachability report items.
	ReachabilityReport *[]AzureReachabilityReportItem `json:"reachabilityReport,omitempty"`
}

// AzureReachabilityReportItem azure reachability report details for a given provider location.
type AzureReachabilityReportItem struct {
	// Provider - The Internet service provider.
	Provider *string `json:"provider,omitempty"`
	// AzureLocation - The Azure region.
	AzureLocation *string `json:"azureLocation,omitempty"`
	// Latencies - List of latency details for each of the time series.
	Latencies *[]AzureReachabilityReportLatencyInfo `json:"latencies,omitempty"`
}

// AzureReachabilityReportLatencyInfo details on latency for a time series.
type AzureReachabilityReportLatencyInfo struct {
	// TimeStamp - The time stamp.
	TimeStamp *date.Time `json:"timeStamp,omitempty"`
	// Score - The relative latency score between 1 and 100, higher values indicating a faster connection.
	Score *int32 `json:"score,omitempty"`
}

// AzureReachabilityReportLocation parameters that define a geographic location.
type AzureReachabilityReportLocation struct {
	// Country - The name of the country.
	Country *string `json:"country,omitempty"`
	// State - The name of the state.
	State *string `json:"state,omitempty"`
	// City - The name of the city or town.
	City *string `json:"city,omitempty"`
}

// AzureReachabilityReportParameters geographic and time constraints for Azure reachability report.
type AzureReachabilityReportParameters struct {
	ProviderLocation *AzureReachabilityReportLocation `json:"providerLocation,omitempty"`
	// Providers - List of Internet service providers.
	Providers *[]string `json:"providers,omitempty"`
	// AzureLocations - Optional Azure regions to scope the query to.
	AzureLocations *[]string `json:"azureLocations,omitempty"`
	// StartTime - The start time for the Azure reachability report.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - The end time for the Azure reachability report.
	EndTime *date.Time `json:"endTime,omitempty"`
}

// BackendAddressPool pool of backend IP addresses.
type BackendAddressPool struct {
	autorest.Response `json:"-"`
	// BackendAddressPoolPropertiesFormat - Properties of load balancer backend address pool.
	*BackendAddressPoolPropertiesFormat `json:"properties,omitempty"`
	// Name - Gets name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for BackendAddressPool.
func (bap BackendAddressPool) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if bap.BackendAddressPoolPropertiesFormat != nil {
		objectMap["properties"] = bap.BackendAddressPoolPropertiesFormat
	}
	if bap.Name != nil {
		objectMap["name"] = bap.Name
	}
	if bap.Etag != nil {
		objectMap["etag"] = bap.Etag
	}
	if bap.ID != nil {
		objectMap["id"] = bap.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for BackendAddressPool struct.
func (bap *BackendAddressPool) 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 {
				var backendAddressPoolPropertiesFormat BackendAddressPoolPropertiesFormat
				err = json.Unmarshal(*v, &backendAddressPoolPropertiesFormat)
				if err != nil {
					return err
				}
				bap.BackendAddressPoolPropertiesFormat = &backendAddressPoolPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				bap.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				bap.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				bap.ID = &ID
			}
		}
	}

	return nil
}

// BackendAddressPoolPropertiesFormat properties of the backend address pool.
type BackendAddressPoolPropertiesFormat struct {
	// BackendIPConfigurations - Gets collection of references to IP addresses defined in network interfaces.
	BackendIPConfigurations *[]InterfaceIPConfiguration `json:"backendIPConfigurations,omitempty"`
	// LoadBalancingRules - Gets load balancing rules that use this backend address pool.
	LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"`
	// OutboundNatRule - Gets outbound rules that use this backend address pool.
	OutboundNatRule *SubResource `json:"outboundNatRule,omitempty"`
	// ProvisioningState - Get provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// BGPCommunity contains bgp community information offered in Service Community resources.
type BGPCommunity struct {
	// ServiceSupportedRegion - The region which the service support. e.g. For O365, region is Global.
	ServiceSupportedRegion *string `json:"serviceSupportedRegion,omitempty"`
	// CommunityName - The name of the bgp community. e.g. Skype.
	CommunityName *string `json:"communityName,omitempty"`
	// CommunityValue - The value of the bgp community. For more information: https://docs.microsoft.com/en-us/azure/expressroute/expressroute-routing.
	CommunityValue *string `json:"communityValue,omitempty"`
	// CommunityPrefixes - The prefixes that the bgp community contains.
	CommunityPrefixes *[]string `json:"communityPrefixes,omitempty"`
	// IsAuthorizedToUse - Customer is authorized to use bgp community or not.
	IsAuthorizedToUse *bool `json:"isAuthorizedToUse,omitempty"`
	// ServiceGroup - The service group of the bgp community contains.
	ServiceGroup *string `json:"serviceGroup,omitempty"`
}

// BgpPeerStatus BGP peer status details
type BgpPeerStatus struct {
	// LocalAddress - The virtual network gateway's local address
	LocalAddress *string `json:"localAddress,omitempty"`
	// Neighbor - The remote BGP peer
	Neighbor *string `json:"neighbor,omitempty"`
	// Asn - The autonomous system number of the remote BGP peer
	Asn *int32 `json:"asn,omitempty"`
	// State - The BGP peer state. Possible values include: 'BgpPeerStateUnknown', 'BgpPeerStateStopped', 'BgpPeerStateIdle', 'BgpPeerStateConnecting', 'BgpPeerStateConnected'
	State BgpPeerState `json:"state,omitempty"`
	// ConnectedDuration - For how long the peering has been up
	ConnectedDuration *string `json:"connectedDuration,omitempty"`
	// RoutesReceived - The number of routes learned from this peer
	RoutesReceived *int64 `json:"routesReceived,omitempty"`
	// MessagesSent - The number of BGP messages sent
	MessagesSent *int64 `json:"messagesSent,omitempty"`
	// MessagesReceived - The number of BGP messages received
	MessagesReceived *int64 `json:"messagesReceived,omitempty"`
}

// BgpPeerStatusListResult response for list BGP peer status API service call
type BgpPeerStatusListResult struct {
	autorest.Response `json:"-"`
	// Value - List of BGP peers
	Value *[]BgpPeerStatus `json:"value,omitempty"`
}

// BgpServiceCommunity service Community Properties.
type BgpServiceCommunity struct {
	*BgpServiceCommunityPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for BgpServiceCommunity.
func (bsc BgpServiceCommunity) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if bsc.BgpServiceCommunityPropertiesFormat != nil {
		objectMap["properties"] = bsc.BgpServiceCommunityPropertiesFormat
	}
	if bsc.ID != nil {
		objectMap["id"] = bsc.ID
	}
	if bsc.Name != nil {
		objectMap["name"] = bsc.Name
	}
	if bsc.Type != nil {
		objectMap["type"] = bsc.Type
	}
	if bsc.Location != nil {
		objectMap["location"] = bsc.Location
	}
	if bsc.Tags != nil {
		objectMap["tags"] = bsc.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for BgpServiceCommunity struct.
func (bsc *BgpServiceCommunity) 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 {
				var bgpServiceCommunityPropertiesFormat BgpServiceCommunityPropertiesFormat
				err = json.Unmarshal(*v, &bgpServiceCommunityPropertiesFormat)
				if err != nil {
					return err
				}
				bsc.BgpServiceCommunityPropertiesFormat = &bgpServiceCommunityPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				bsc.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				bsc.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				bsc.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				bsc.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				bsc.Tags = tags
			}
		}
	}

	return nil
}

// BgpServiceCommunityListResult response for the ListServiceCommunity API service call.
type BgpServiceCommunityListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of service community resources.
	Value *[]BgpServiceCommunity `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// BgpServiceCommunityListResultIterator provides access to a complete listing of BgpServiceCommunity
// values.
type BgpServiceCommunityListResultIterator struct {
	i    int
	page BgpServiceCommunityListResultPage
}

// 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 *BgpServiceCommunityListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/BgpServiceCommunityListResultIterator.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 *BgpServiceCommunityListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter BgpServiceCommunityListResultIterator) 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 BgpServiceCommunityListResultIterator) Response() BgpServiceCommunityListResult {
	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 BgpServiceCommunityListResultIterator) Value() BgpServiceCommunity {
	if !iter.page.NotDone() {
		return BgpServiceCommunity{}
	}
	return iter.page.Values()[iter.i]
}

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

// bgpServiceCommunityListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (bsclr BgpServiceCommunityListResult) bgpServiceCommunityListResultPreparer(ctx context.Context) (*http.Request, error) {
	if bsclr.NextLink == nil || len(to.String(bsclr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(bsclr.NextLink)))
}

// BgpServiceCommunityListResultPage contains a page of BgpServiceCommunity values.
type BgpServiceCommunityListResultPage struct {
	fn    func(context.Context, BgpServiceCommunityListResult) (BgpServiceCommunityListResult, error)
	bsclr BgpServiceCommunityListResult
}

// 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 *BgpServiceCommunityListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/BgpServiceCommunityListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.bsclr)
	if err != nil {
		return err
	}
	page.bsclr = next
	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 *BgpServiceCommunityListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page BgpServiceCommunityListResultPage) Response() BgpServiceCommunityListResult {
	return page.bsclr
}

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

// BgpServiceCommunityPropertiesFormat properties of Service Community.
type BgpServiceCommunityPropertiesFormat struct {
	// ServiceName - The name of the bgp community. e.g. Skype.
	ServiceName *string `json:"serviceName,omitempty"`
	// BgpCommunities - Get a list of bgp communities.
	BgpCommunities *[]BGPCommunity `json:"bgpCommunities,omitempty"`
}

// BgpSettings BGP settings details
type BgpSettings struct {
	// Asn - The BGP speaker's ASN.
	Asn *int64 `json:"asn,omitempty"`
	// BgpPeeringAddress - The BGP peering address and BGP identifier of this BGP speaker.
	BgpPeeringAddress *string `json:"bgpPeeringAddress,omitempty"`
	// PeerWeight - The weight added to routes learned from this BGP speaker.
	PeerWeight *int32 `json:"peerWeight,omitempty"`
}

// ConnectionResetSharedKey the virtual network connection reset shared key
type ConnectionResetSharedKey struct {
	autorest.Response `json:"-"`
	// KeyLength - The virtual network connection reset shared key length, should between 1 and 128.
	KeyLength *int32 `json:"keyLength,omitempty"`
}

// ConnectionSharedKey response for GetConnectionSharedKey API service call
type ConnectionSharedKey struct {
	autorest.Response `json:"-"`
	// Value - The virtual network connection shared key value.
	Value *string `json:"value,omitempty"`
}

// ConnectivityDestination parameters that define destination of connection.
type ConnectivityDestination struct {
	// ResourceID - The ID of the resource to which a connection attempt will be made.
	ResourceID *string `json:"resourceId,omitempty"`
	// Address - The IP address or URI the resource to which a connection attempt will be made.
	Address *string `json:"address,omitempty"`
	// Port - Port on which check connectivity will be performed.
	Port *int32 `json:"port,omitempty"`
}

// ConnectivityHop information about a hop between the source and the destination.
type ConnectivityHop struct {
	// Type - The type of the hop.
	Type *string `json:"type,omitempty"`
	// ID - The ID of the hop.
	ID *string `json:"id,omitempty"`
	// Address - The IP address of the hop.
	Address *string `json:"address,omitempty"`
	// ResourceID - The ID of the resource corresponding to this hop.
	ResourceID *string `json:"resourceId,omitempty"`
	// NextHopIds - List of next hop identifiers.
	NextHopIds *[]string `json:"nextHopIds,omitempty"`
	// Issues - List of issues.
	Issues *[]ConnectivityIssue `json:"issues,omitempty"`
}

// ConnectivityInformation information on the connectivity status.
type ConnectivityInformation struct {
	autorest.Response `json:"-"`
	// Hops - List of hops between the source and the destination.
	Hops *[]ConnectivityHop `json:"hops,omitempty"`
	// ConnectionStatus - The connection status. Possible values include: 'ConnectionStatusUnknown', 'ConnectionStatusConnected', 'ConnectionStatusDisconnected', 'ConnectionStatusDegraded'
	ConnectionStatus ConnectionStatus `json:"connectionStatus,omitempty"`
	// AvgLatencyInMs - Average latency in milliseconds.
	AvgLatencyInMs *int32 `json:"avgLatencyInMs,omitempty"`
	// MinLatencyInMs - Minimum latency in milliseconds.
	MinLatencyInMs *int32 `json:"minLatencyInMs,omitempty"`
	// MaxLatencyInMs - Maximum latency in milliseconds.
	MaxLatencyInMs *int32 `json:"maxLatencyInMs,omitempty"`
	// ProbesSent - Total number of probes sent.
	ProbesSent *int32 `json:"probesSent,omitempty"`
	// ProbesFailed - Number of failed probes.
	ProbesFailed *int32 `json:"probesFailed,omitempty"`
}

// ConnectivityIssue information about an issue encountered in the process of checking for connectivity.
type ConnectivityIssue struct {
	// Origin - The origin of the issue. Possible values include: 'OriginLocal', 'OriginInbound', 'OriginOutbound'
	Origin Origin `json:"origin,omitempty"`
	// Severity - The severity of the issue. Possible values include: 'SeverityError', 'SeverityWarning'
	Severity Severity `json:"severity,omitempty"`
	// Type - The type of issue. Possible values include: 'IssueTypeUnknown', 'IssueTypeAgentStopped', 'IssueTypeGuestFirewall', 'IssueTypeDNSResolution', 'IssueTypeSocketBind', 'IssueTypeNetworkSecurityRule', 'IssueTypeUserDefinedRoute', 'IssueTypePortThrottled', 'IssueTypePlatform'
	Type IssueType `json:"type,omitempty"`
	// Context - Provides additional context on the issue.
	Context *[]map[string]*string `json:"context,omitempty"`
}

// ConnectivityParameters parameters that determine how the connectivity check will be performed.
type ConnectivityParameters struct {
	Source      *ConnectivitySource      `json:"source,omitempty"`
	Destination *ConnectivityDestination `json:"destination,omitempty"`
}

// ConnectivitySource parameters that define the source of the connection.
type ConnectivitySource struct {
	// ResourceID - The ID of the resource from which a connectivity check will be initiated.
	ResourceID *string `json:"resourceId,omitempty"`
	// Port - The source port from which a connectivity check will be performed.
	Port *int32 `json:"port,omitempty"`
}

// DhcpOptions dhcpOptions contains an array of DNS servers available to VMs deployed in the virtual
// network. Standard DHCP option for a subnet overrides VNET DHCP options.
type DhcpOptions struct {
	// DNSServers - The list of DNS servers IP addresses.
	DNSServers *[]string `json:"dnsServers,omitempty"`
}

// Dimension dimension of the metric.
type Dimension struct {
	// Name - The name of the dimension.
	Name *string `json:"name,omitempty"`
	// DisplayName - The display name of the dimension.
	DisplayName *string `json:"displayName,omitempty"`
	// InternalName - The internal name of the dimension.
	InternalName *string `json:"internalName,omitempty"`
}

// DNSNameAvailabilityResult response for the CheckDnsNameAvailability API service call.
type DNSNameAvailabilityResult struct {
	autorest.Response `json:"-"`
	// Available - Domain availability (True/False).
	Available *bool `json:"available,omitempty"`
}

// EffectiveNetworkSecurityGroup effective network security group.
type EffectiveNetworkSecurityGroup struct {
	// NetworkSecurityGroup - The ID of network security group that is applied.
	NetworkSecurityGroup *SubResource `json:"networkSecurityGroup,omitempty"`
	// Association - Associated resources.
	Association *EffectiveNetworkSecurityGroupAssociation `json:"association,omitempty"`
	// EffectiveSecurityRules - A collection of effective security rules.
	EffectiveSecurityRules *[]EffectiveNetworkSecurityRule `json:"effectiveSecurityRules,omitempty"`
	// TagMap - Mapping of tags to list of IP Addresses included within the tag.
	TagMap map[string][]string `json:"tagMap"`
}

// MarshalJSON is the custom marshaler for EffectiveNetworkSecurityGroup.
func (ensg EffectiveNetworkSecurityGroup) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ensg.NetworkSecurityGroup != nil {
		objectMap["networkSecurityGroup"] = ensg.NetworkSecurityGroup
	}
	if ensg.Association != nil {
		objectMap["association"] = ensg.Association
	}
	if ensg.EffectiveSecurityRules != nil {
		objectMap["effectiveSecurityRules"] = ensg.EffectiveSecurityRules
	}
	if ensg.TagMap != nil {
		objectMap["tagMap"] = ensg.TagMap
	}
	return json.Marshal(objectMap)
}

// EffectiveNetworkSecurityGroupAssociation the effective network security group association.
type EffectiveNetworkSecurityGroupAssociation struct {
	// Subnet - The ID of the subnet if assigned.
	Subnet *SubResource `json:"subnet,omitempty"`
	// NetworkInterface - The ID of the network interface if assigned.
	NetworkInterface *SubResource `json:"networkInterface,omitempty"`
}

// EffectiveNetworkSecurityGroupListResult response for list effective network security groups API service
// call.
type EffectiveNetworkSecurityGroupListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of effective network security groups.
	Value *[]EffectiveNetworkSecurityGroup `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// EffectiveNetworkSecurityRule effective network security rules.
type EffectiveNetworkSecurityRule struct {
	// Name - The name of the security rule specified by the user (if created by the user).
	Name *string `json:"name,omitempty"`
	// Protocol - The network protocol this rule applies to. Possible values are: 'Tcp', 'Udp', and 'All'. Possible values include: 'TCP', 'UDP', 'All'
	Protocol EffectiveSecurityRuleProtocol `json:"protocol,omitempty"`
	// SourcePortRange - The source port or range.
	SourcePortRange *string `json:"sourcePortRange,omitempty"`
	// DestinationPortRange - The destination port or range.
	DestinationPortRange *string `json:"destinationPortRange,omitempty"`
	// SourcePortRanges - The source port ranges. Expected values include a single integer between 0 and 65535, a range using '-' as seperator (e.g. 100-400), or an asterix (*)
	SourcePortRanges *[]string `json:"sourcePortRanges,omitempty"`
	// DestinationPortRanges - The destination port ranges. Expected values include a single integer between 0 and 65535, a range using '-' as seperator (e.g. 100-400), or an asterix (*)
	DestinationPortRanges *[]string `json:"destinationPortRanges,omitempty"`
	// SourceAddressPrefix - The source address prefix.
	SourceAddressPrefix *string `json:"sourceAddressPrefix,omitempty"`
	// DestinationAddressPrefix - The destination address prefix.
	DestinationAddressPrefix *string `json:"destinationAddressPrefix,omitempty"`
	// SourceAddressPrefixes - The source address prefixes. Expected values include CIDR IP ranges, Default Tags (VirtualNetwork, AureLoadBalancer, Internet), System Tags, and the asterix (*).
	SourceAddressPrefixes *[]string `json:"sourceAddressPrefixes,omitempty"`
	// DestinationAddressPrefixes - The destination address prefixes. Expected values include CIDR IP ranges, Default Tags (VirtualNetwork, AureLoadBalancer, Internet), System Tags, and the asterix (*).
	DestinationAddressPrefixes *[]string `json:"destinationAddressPrefixes,omitempty"`
	// ExpandedSourceAddressPrefix - The expanded source address prefix.
	ExpandedSourceAddressPrefix *[]string `json:"expandedSourceAddressPrefix,omitempty"`
	// ExpandedDestinationAddressPrefix - Expanded destination address prefix.
	ExpandedDestinationAddressPrefix *[]string `json:"expandedDestinationAddressPrefix,omitempty"`
	// Access - Whether network traffic is allowed or denied. Possible values are: 'Allow' and 'Deny'. Possible values include: 'SecurityRuleAccessAllow', 'SecurityRuleAccessDeny'
	Access SecurityRuleAccess `json:"access,omitempty"`
	// Priority - The priority of the rule.
	Priority *int32 `json:"priority,omitempty"`
	// Direction - The direction of the rule. Possible values are: 'Inbound and Outbound'. Possible values include: 'SecurityRuleDirectionInbound', 'SecurityRuleDirectionOutbound'
	Direction SecurityRuleDirection `json:"direction,omitempty"`
}

// EffectiveRoute effective Route
type EffectiveRoute struct {
	// Name - The name of the user defined route. This is optional.
	Name *string `json:"name,omitempty"`
	// Source - Who created the route. Possible values are: 'Unknown', 'User', 'VirtualNetworkGateway', and 'Default'. Possible values include: 'EffectiveRouteSourceUnknown', 'EffectiveRouteSourceUser', 'EffectiveRouteSourceVirtualNetworkGateway', 'EffectiveRouteSourceDefault'
	Source EffectiveRouteSource `json:"source,omitempty"`
	// State - The value of effective route. Possible values are: 'Active' and 'Invalid'. Possible values include: 'Active', 'Invalid'
	State EffectiveRouteState `json:"state,omitempty"`
	// AddressPrefix - The address prefixes of the effective routes in CIDR notation.
	AddressPrefix *[]string `json:"addressPrefix,omitempty"`
	// NextHopIPAddress - The IP address of the next hop of the effective route.
	NextHopIPAddress *[]string `json:"nextHopIpAddress,omitempty"`
	// NextHopType - The type of Azure hop the packet should be sent to. Possible values are: 'VirtualNetworkGateway', 'VnetLocal', 'Internet', 'VirtualAppliance', and 'None'. Possible values include: 'RouteNextHopTypeVirtualNetworkGateway', 'RouteNextHopTypeVnetLocal', 'RouteNextHopTypeInternet', 'RouteNextHopTypeVirtualAppliance', 'RouteNextHopTypeNone'
	NextHopType RouteNextHopType `json:"nextHopType,omitempty"`
}

// EffectiveRouteListResult response for list effective route API service call.
type EffectiveRouteListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of effective routes.
	Value *[]EffectiveRoute `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// EndpointServiceResult endpoint service.
type EndpointServiceResult struct {
	// Name - Name of the endpoint service.
	Name *string `json:"name,omitempty"`
	// Type - Type of the endpoint service.
	Type *string `json:"type,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// EndpointServicesListResult response for the ListAvailableEndpointServices API service call.
type EndpointServicesListResult struct {
	autorest.Response `json:"-"`
	// Value - List of available endpoint services in a region.
	Value *[]EndpointServiceResult `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// EndpointServicesListResultIterator provides access to a complete listing of EndpointServiceResult
// values.
type EndpointServicesListResultIterator struct {
	i    int
	page EndpointServicesListResultPage
}

// 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 *EndpointServicesListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/EndpointServicesListResultIterator.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 *EndpointServicesListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter EndpointServicesListResultIterator) 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 EndpointServicesListResultIterator) Response() EndpointServicesListResult {
	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 EndpointServicesListResultIterator) Value() EndpointServiceResult {
	if !iter.page.NotDone() {
		return EndpointServiceResult{}
	}
	return iter.page.Values()[iter.i]
}

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

// endpointServicesListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (eslr EndpointServicesListResult) endpointServicesListResultPreparer(ctx context.Context) (*http.Request, error) {
	if eslr.NextLink == nil || len(to.String(eslr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(eslr.NextLink)))
}

// EndpointServicesListResultPage contains a page of EndpointServiceResult values.
type EndpointServicesListResultPage struct {
	fn   func(context.Context, EndpointServicesListResult) (EndpointServicesListResult, error)
	eslr EndpointServicesListResult
}

// 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 *EndpointServicesListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/EndpointServicesListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.eslr)
	if err != nil {
		return err
	}
	page.eslr = next
	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 *EndpointServicesListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page EndpointServicesListResultPage) Response() EndpointServicesListResult {
	return page.eslr
}

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

// Error ...
type Error struct {
	Code       *string         `json:"code,omitempty"`
	Message    *string         `json:"message,omitempty"`
	Target     *string         `json:"target,omitempty"`
	Details    *[]ErrorDetails `json:"details,omitempty"`
	InnerError *string         `json:"innerError,omitempty"`
}

// ErrorDetails ...
type ErrorDetails struct {
	Code    *string `json:"code,omitempty"`
	Target  *string `json:"target,omitempty"`
	Message *string `json:"message,omitempty"`
}

// ExpressRouteCircuit expressRouteCircuit resource
type ExpressRouteCircuit struct {
	autorest.Response `json:"-"`
	// Sku - The SKU.
	Sku                                  *ExpressRouteCircuitSku `json:"sku,omitempty"`
	*ExpressRouteCircuitPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ExpressRouteCircuit.
func (erc ExpressRouteCircuit) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if erc.Sku != nil {
		objectMap["sku"] = erc.Sku
	}
	if erc.ExpressRouteCircuitPropertiesFormat != nil {
		objectMap["properties"] = erc.ExpressRouteCircuitPropertiesFormat
	}
	if erc.Etag != nil {
		objectMap["etag"] = erc.Etag
	}
	if erc.ID != nil {
		objectMap["id"] = erc.ID
	}
	if erc.Name != nil {
		objectMap["name"] = erc.Name
	}
	if erc.Type != nil {
		objectMap["type"] = erc.Type
	}
	if erc.Location != nil {
		objectMap["location"] = erc.Location
	}
	if erc.Tags != nil {
		objectMap["tags"] = erc.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ExpressRouteCircuit struct.
func (erc *ExpressRouteCircuit) 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 "sku":
			if v != nil {
				var sku ExpressRouteCircuitSku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				erc.Sku = &sku
			}
		case "properties":
			if v != nil {
				var expressRouteCircuitPropertiesFormat ExpressRouteCircuitPropertiesFormat
				err = json.Unmarshal(*v, &expressRouteCircuitPropertiesFormat)
				if err != nil {
					return err
				}
				erc.ExpressRouteCircuitPropertiesFormat = &expressRouteCircuitPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				erc.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				erc.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				erc.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				erc.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				erc.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				erc.Tags = tags
			}
		}
	}

	return nil
}

// ExpressRouteCircuitArpTable the ARP table associated with the ExpressRouteCircuit.
type ExpressRouteCircuitArpTable struct {
	// Age - Age
	Age *int32 `json:"age,omitempty"`
	// Interface - Interface
	Interface *string `json:"interface,omitempty"`
	// IPAddress - The IP address.
	IPAddress *string `json:"ipAddress,omitempty"`
	// MacAddress - The MAC address.
	MacAddress *string `json:"macAddress,omitempty"`
}

// ExpressRouteCircuitAuthorization authorization in an ExpressRouteCircuit resource.
type ExpressRouteCircuitAuthorization struct {
	autorest.Response              `json:"-"`
	*AuthorizationPropertiesFormat `json:"properties,omitempty"`
	// Name - Gets name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ExpressRouteCircuitAuthorization.
func (erca ExpressRouteCircuitAuthorization) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if erca.AuthorizationPropertiesFormat != nil {
		objectMap["properties"] = erca.AuthorizationPropertiesFormat
	}
	if erca.Name != nil {
		objectMap["name"] = erca.Name
	}
	if erca.Etag != nil {
		objectMap["etag"] = erca.Etag
	}
	if erca.ID != nil {
		objectMap["id"] = erca.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ExpressRouteCircuitAuthorization struct.
func (erca *ExpressRouteCircuitAuthorization) 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 {
				var authorizationPropertiesFormat AuthorizationPropertiesFormat
				err = json.Unmarshal(*v, &authorizationPropertiesFormat)
				if err != nil {
					return err
				}
				erca.AuthorizationPropertiesFormat = &authorizationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				erca.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				erca.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				erca.ID = &ID
			}
		}
	}

	return nil
}

// ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (erca ExpressRouteCircuitAuthorization, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if erca.Response.Response, err = future.GetResult(sender); err == nil && erca.Response.Response.StatusCode != http.StatusNoContent {
		erca, err = client.CreateOrUpdateResponder(erca.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsCreateOrUpdateFuture", "Result", erca.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitAuthorizationsDeleteFuture an abstraction for monitoring and retrieving the results
// of a long-running operation.
type ExpressRouteCircuitAuthorizationsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitAuthorizationsDeleteFuture) Result(client ExpressRouteCircuitAuthorizationsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitAuthorizationsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitAuthorizationsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ExpressRouteCircuitListResult response for ListExpressRouteCircuit API service call.
type ExpressRouteCircuitListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of ExpressRouteCircuits in a resource group.
	Value *[]ExpressRouteCircuit `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteCircuitListResultIterator provides access to a complete listing of ExpressRouteCircuit
// values.
type ExpressRouteCircuitListResultIterator struct {
	i    int
	page ExpressRouteCircuitListResultPage
}

// 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 *ExpressRouteCircuitListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteCircuitListResultIterator.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 *ExpressRouteCircuitListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ExpressRouteCircuitListResultIterator) 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 ExpressRouteCircuitListResultIterator) Response() ExpressRouteCircuitListResult {
	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 ExpressRouteCircuitListResultIterator) Value() ExpressRouteCircuit {
	if !iter.page.NotDone() {
		return ExpressRouteCircuit{}
	}
	return iter.page.Values()[iter.i]
}

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

// expressRouteCircuitListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (erclr ExpressRouteCircuitListResult) expressRouteCircuitListResultPreparer(ctx context.Context) (*http.Request, error) {
	if erclr.NextLink == nil || len(to.String(erclr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(erclr.NextLink)))
}

// ExpressRouteCircuitListResultPage contains a page of ExpressRouteCircuit values.
type ExpressRouteCircuitListResultPage struct {
	fn    func(context.Context, ExpressRouteCircuitListResult) (ExpressRouteCircuitListResult, error)
	erclr ExpressRouteCircuitListResult
}

// 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 *ExpressRouteCircuitListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteCircuitListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.erclr)
	if err != nil {
		return err
	}
	page.erclr = next
	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 *ExpressRouteCircuitListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ExpressRouteCircuitListResultPage) Response() ExpressRouteCircuitListResult {
	return page.erclr
}

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

// ExpressRouteCircuitPeering peering in an ExpressRouteCircuit resource.
type ExpressRouteCircuitPeering struct {
	autorest.Response                           `json:"-"`
	*ExpressRouteCircuitPeeringPropertiesFormat `json:"properties,omitempty"`
	// Name - Gets name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ExpressRouteCircuitPeering.
func (ercp ExpressRouteCircuitPeering) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ercp.ExpressRouteCircuitPeeringPropertiesFormat != nil {
		objectMap["properties"] = ercp.ExpressRouteCircuitPeeringPropertiesFormat
	}
	if ercp.Name != nil {
		objectMap["name"] = ercp.Name
	}
	if ercp.Etag != nil {
		objectMap["etag"] = ercp.Etag
	}
	if ercp.ID != nil {
		objectMap["id"] = ercp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ExpressRouteCircuitPeering struct.
func (ercp *ExpressRouteCircuitPeering) 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 {
				var expressRouteCircuitPeeringPropertiesFormat ExpressRouteCircuitPeeringPropertiesFormat
				err = json.Unmarshal(*v, &expressRouteCircuitPeeringPropertiesFormat)
				if err != nil {
					return err
				}
				ercp.ExpressRouteCircuitPeeringPropertiesFormat = &expressRouteCircuitPeeringPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ercp.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				ercp.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ercp.ID = &ID
			}
		}
	}

	return nil
}

// ExpressRouteCircuitPeeringConfig specifies the peering configuration.
type ExpressRouteCircuitPeeringConfig struct {
	// AdvertisedPublicPrefixes - The reference of AdvertisedPublicPrefixes.
	AdvertisedPublicPrefixes *[]string `json:"advertisedPublicPrefixes,omitempty"`
	// AdvertisedCommunities - The communities of bgp peering. Spepcified for microsoft peering
	AdvertisedCommunities *[]string `json:"advertisedCommunities,omitempty"`
	// AdvertisedPublicPrefixesState - AdvertisedPublicPrefixState of the Peering resource. Possible values are 'NotConfigured', 'Configuring', 'Configured', and 'ValidationNeeded'. Possible values include: 'NotConfigured', 'Configuring', 'Configured', 'ValidationNeeded'
	AdvertisedPublicPrefixesState ExpressRouteCircuitPeeringAdvertisedPublicPrefixState `json:"advertisedPublicPrefixesState,omitempty"`
	// LegacyMode - The legacy mode of the peering.
	LegacyMode *int32 `json:"legacyMode,omitempty"`
	// CustomerASN - The CustomerASN of the peering.
	CustomerASN *int32 `json:"customerASN,omitempty"`
	// RoutingRegistryName - The RoutingRegistryName of the configuration.
	RoutingRegistryName *string `json:"routingRegistryName,omitempty"`
}

// ExpressRouteCircuitPeeringListResult response for ListPeering API service call retrieves all peerings
// that belong to an ExpressRouteCircuit.
type ExpressRouteCircuitPeeringListResult struct {
	autorest.Response `json:"-"`
	// Value - The peerings in an express route circuit.
	Value *[]ExpressRouteCircuitPeering `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteCircuitPeeringListResultIterator provides access to a complete listing of
// ExpressRouteCircuitPeering values.
type ExpressRouteCircuitPeeringListResultIterator struct {
	i    int
	page ExpressRouteCircuitPeeringListResultPage
}

// 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 *ExpressRouteCircuitPeeringListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteCircuitPeeringListResultIterator.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 *ExpressRouteCircuitPeeringListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ExpressRouteCircuitPeeringListResultIterator) 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 ExpressRouteCircuitPeeringListResultIterator) Response() ExpressRouteCircuitPeeringListResult {
	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 ExpressRouteCircuitPeeringListResultIterator) Value() ExpressRouteCircuitPeering {
	if !iter.page.NotDone() {
		return ExpressRouteCircuitPeering{}
	}
	return iter.page.Values()[iter.i]
}

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

// expressRouteCircuitPeeringListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (ercplr ExpressRouteCircuitPeeringListResult) expressRouteCircuitPeeringListResultPreparer(ctx context.Context) (*http.Request, error) {
	if ercplr.NextLink == nil || len(to.String(ercplr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(ercplr.NextLink)))
}

// ExpressRouteCircuitPeeringListResultPage contains a page of ExpressRouteCircuitPeering values.
type ExpressRouteCircuitPeeringListResultPage struct {
	fn     func(context.Context, ExpressRouteCircuitPeeringListResult) (ExpressRouteCircuitPeeringListResult, error)
	ercplr ExpressRouteCircuitPeeringListResult
}

// 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 *ExpressRouteCircuitPeeringListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteCircuitPeeringListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.ercplr)
	if err != nil {
		return err
	}
	page.ercplr = next
	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 *ExpressRouteCircuitPeeringListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ExpressRouteCircuitPeeringListResultPage) Response() ExpressRouteCircuitPeeringListResult {
	return page.ercplr
}

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

// ExpressRouteCircuitPeeringPropertiesFormat ...
type ExpressRouteCircuitPeeringPropertiesFormat struct {
	// PeeringType - The PeeringType. Possible values are: 'AzurePublicPeering', 'AzurePrivatePeering', and 'MicrosoftPeering'. Possible values include: 'AzurePublicPeering', 'AzurePrivatePeering', 'MicrosoftPeering'
	PeeringType ExpressRouteCircuitPeeringType `json:"peeringType,omitempty"`
	// State - The state of peering. Possible values are: 'Disabled' and 'Enabled'. Possible values include: 'ExpressRouteCircuitPeeringStateDisabled', 'ExpressRouteCircuitPeeringStateEnabled'
	State ExpressRouteCircuitPeeringState `json:"state,omitempty"`
	// AzureASN - The Azure ASN.
	AzureASN *int32 `json:"azureASN,omitempty"`
	// PeerASN - The peer ASN.
	PeerASN *int32 `json:"peerASN,omitempty"`
	// PrimaryPeerAddressPrefix - The primary address prefix.
	PrimaryPeerAddressPrefix *string `json:"primaryPeerAddressPrefix,omitempty"`
	// SecondaryPeerAddressPrefix - The secondary address prefix.
	SecondaryPeerAddressPrefix *string `json:"secondaryPeerAddressPrefix,omitempty"`
	// PrimaryAzurePort - The primary port.
	PrimaryAzurePort *string `json:"primaryAzurePort,omitempty"`
	// SecondaryAzurePort - The secondary port.
	SecondaryAzurePort *string `json:"secondaryAzurePort,omitempty"`
	// SharedKey - The shared key.
	SharedKey *string `json:"sharedKey,omitempty"`
	// VlanID - The VLAN ID.
	VlanID *int32 `json:"vlanId,omitempty"`
	// MicrosoftPeeringConfig - The Microsoft peering configuration.
	MicrosoftPeeringConfig *ExpressRouteCircuitPeeringConfig `json:"microsoftPeeringConfig,omitempty"`
	// Stats - Gets peering stats.
	Stats *ExpressRouteCircuitStats `json:"stats,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// GatewayManagerEtag - The GatewayManager Etag.
	GatewayManagerEtag *string `json:"gatewayManagerEtag,omitempty"`
	// LastModifiedBy - Gets whether the provider or the customer last modified the peering.
	LastModifiedBy *string `json:"lastModifiedBy,omitempty"`
	// RouteFilter - The reference of the RouteFilter resource.
	RouteFilter *RouteFilter `json:"routeFilter,omitempty"`
	// Ipv6PeeringConfig - The IPv6 peering configuration.
	Ipv6PeeringConfig *Ipv6ExpressRouteCircuitPeeringConfig `json:"ipv6PeeringConfig,omitempty"`
}

// ExpressRouteCircuitPeeringsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results
// of a long-running operation.
type ExpressRouteCircuitPeeringsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitPeeringsCreateOrUpdateFuture) Result(client ExpressRouteCircuitPeeringsClient) (ercp ExpressRouteCircuitPeering, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ercp.Response.Response, err = future.GetResult(sender); err == nil && ercp.Response.Response.StatusCode != http.StatusNoContent {
		ercp, err = client.CreateOrUpdateResponder(ercp.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsCreateOrUpdateFuture", "Result", ercp.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitPeeringsDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitPeeringsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitPeeringsDeleteFuture) Result(client ExpressRouteCircuitPeeringsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitPeeringsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitPeeringsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ExpressRouteCircuitPropertiesFormat properties of ExpressRouteCircuit.
type ExpressRouteCircuitPropertiesFormat struct {
	// AllowClassicOperations - Allow classic operations
	AllowClassicOperations *bool `json:"allowClassicOperations,omitempty"`
	// CircuitProvisioningState - The CircuitProvisioningState state of the resource.
	CircuitProvisioningState *string `json:"circuitProvisioningState,omitempty"`
	// ServiceProviderProvisioningState - The ServiceProviderProvisioningState state of the resource. Possible values are 'NotProvisioned', 'Provisioning', 'Provisioned', and 'Deprovisioning'. Possible values include: 'NotProvisioned', 'Provisioning', 'Provisioned', 'Deprovisioning'
	ServiceProviderProvisioningState ServiceProviderProvisioningState `json:"serviceProviderProvisioningState,omitempty"`
	// Authorizations - The list of authorizations.
	Authorizations *[]ExpressRouteCircuitAuthorization `json:"authorizations,omitempty"`
	// Peerings - The list of peerings.
	Peerings *[]ExpressRouteCircuitPeering `json:"peerings,omitempty"`
	// ServiceKey - The ServiceKey.
	ServiceKey *string `json:"serviceKey,omitempty"`
	// ServiceProviderNotes - The ServiceProviderNotes.
	ServiceProviderNotes *string `json:"serviceProviderNotes,omitempty"`
	// ServiceProviderProperties - The ServiceProviderProperties.
	ServiceProviderProperties *ExpressRouteCircuitServiceProviderProperties `json:"serviceProviderProperties,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// GatewayManagerEtag - The GatewayManager Etag.
	GatewayManagerEtag *string `json:"gatewayManagerEtag,omitempty"`
}

// ExpressRouteCircuitRoutesTable the routes table associated with the ExpressRouteCircuit
type ExpressRouteCircuitRoutesTable struct {
	// NetworkProperty - network
	NetworkProperty *string `json:"network,omitempty"`
	// NextHop - nextHop
	NextHop *string `json:"nextHop,omitempty"`
	// LocPrf - locPrf
	LocPrf *string `json:"locPrf,omitempty"`
	// Weight - weight.
	Weight *int32 `json:"weight,omitempty"`
	// Path - path
	Path *string `json:"path,omitempty"`
}

// ExpressRouteCircuitRoutesTableSummary the routes table associated with the ExpressRouteCircuit.
type ExpressRouteCircuitRoutesTableSummary struct {
	// Neighbor - Neighbor
	Neighbor *string `json:"neighbor,omitempty"`
	// V - BGP version number spoken to the neighbor.
	V *int32 `json:"v,omitempty"`
	// As - Autonomous system number.
	As *int32 `json:"as,omitempty"`
	// UpDown - The length of time that the BGP session has been in the Established state, or the current status if not in the Established state.
	UpDown *string `json:"upDown,omitempty"`
	// StatePfxRcd - Current state of the BGP session, and the number of prefixes that have been received from a neighbor or peer group.
	StatePfxRcd *string `json:"statePfxRcd,omitempty"`
}

// ExpressRouteCircuitsArpTableListResult response for ListArpTable associated with the Express Route
// Circuits API.
type ExpressRouteCircuitsArpTableListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets list of the ARP table.
	Value *[]ExpressRouteCircuitArpTable `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteCircuitsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsCreateOrUpdateFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if erc.Response.Response, err = future.GetResult(sender); err == nil && erc.Response.Response.StatusCode != http.StatusNoContent {
		erc, err = client.CreateOrUpdateResponder(erc.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsCreateOrUpdateFuture", "Result", erc.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitsDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsDeleteFuture) Result(client ExpressRouteCircuitsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ExpressRouteCircuitServiceProviderProperties contains ServiceProviderProperties in an
// ExpressRouteCircuit.
type ExpressRouteCircuitServiceProviderProperties struct {
	// ServiceProviderName - The serviceProviderName.
	ServiceProviderName *string `json:"serviceProviderName,omitempty"`
	// PeeringLocation - The peering location.
	PeeringLocation *string `json:"peeringLocation,omitempty"`
	// BandwidthInMbps - The BandwidthInMbps.
	BandwidthInMbps *int32 `json:"bandwidthInMbps,omitempty"`
}

// ExpressRouteCircuitSku contains SKU in an ExpressRouteCircuit.
type ExpressRouteCircuitSku struct {
	// Name - The name of the SKU.
	Name *string `json:"name,omitempty"`
	// Tier - The tier of the SKU. Possible values are 'Standard' and 'Premium'. Possible values include: 'ExpressRouteCircuitSkuTierStandard', 'ExpressRouteCircuitSkuTierPremium'
	Tier ExpressRouteCircuitSkuTier `json:"tier,omitempty"`
	// Family - The family of the SKU. Possible values are: 'UnlimitedData' and 'MeteredData'. Possible values include: 'UnlimitedData', 'MeteredData'
	Family ExpressRouteCircuitSkuFamily `json:"family,omitempty"`
}

// ExpressRouteCircuitsListArpTableFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitsListArpTableFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsListArpTableFuture) Result(client ExpressRouteCircuitsClient) (ercatlr ExpressRouteCircuitsArpTableListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListArpTableFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ercatlr.Response.Response, err = future.GetResult(sender); err == nil && ercatlr.Response.Response.StatusCode != http.StatusNoContent {
		ercatlr, err = client.ListArpTableResponder(ercatlr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListArpTableFuture", "Result", ercatlr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitsListRoutesTableFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitsListRoutesTableFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsListRoutesTableFuture) Result(client ExpressRouteCircuitsClient) (ercrtlr ExpressRouteCircuitsRoutesTableListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ercrtlr.Response.Response, err = future.GetResult(sender); err == nil && ercrtlr.Response.Response.StatusCode != http.StatusNoContent {
		ercrtlr, err = client.ListRoutesTableResponder(ercrtlr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableFuture", "Result", ercrtlr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitsListRoutesTableSummaryFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type ExpressRouteCircuitsListRoutesTableSummaryFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsListRoutesTableSummaryFuture) Result(client ExpressRouteCircuitsClient) (ercrtslr ExpressRouteCircuitsRoutesTableSummaryListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsListRoutesTableSummaryFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ercrtslr.Response.Response, err = future.GetResult(sender); err == nil && ercrtslr.Response.Response.StatusCode != http.StatusNoContent {
		ercrtslr, err = client.ListRoutesTableSummaryResponder(ercrtslr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsListRoutesTableSummaryFuture", "Result", ercrtslr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteCircuitsRoutesTableListResult response for ListRoutesTable associated with the Express Route
// Circuits API.
type ExpressRouteCircuitsRoutesTableListResult struct {
	autorest.Response `json:"-"`
	// Value - The list of routes table.
	Value *[]ExpressRouteCircuitRoutesTable `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteCircuitsRoutesTableSummaryListResult response for ListRoutesTable associated with the
// Express Route Circuits API.
type ExpressRouteCircuitsRoutesTableSummaryListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of the routes table.
	Value *[]ExpressRouteCircuitRoutesTableSummary `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteCircuitStats contains stats associated with the peering.
type ExpressRouteCircuitStats struct {
	autorest.Response `json:"-"`
	// PrimarybytesIn - Gets BytesIn of the peering.
	PrimarybytesIn *int64 `json:"primarybytesIn,omitempty"`
	// PrimarybytesOut - Gets BytesOut of the peering.
	PrimarybytesOut *int64 `json:"primarybytesOut,omitempty"`
	// SecondarybytesIn - Gets BytesIn of the peering.
	SecondarybytesIn *int64 `json:"secondarybytesIn,omitempty"`
	// SecondarybytesOut - Gets BytesOut of the peering.
	SecondarybytesOut *int64 `json:"secondarybytesOut,omitempty"`
}

// ExpressRouteCircuitsUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type ExpressRouteCircuitsUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *ExpressRouteCircuitsUpdateTagsFuture) Result(client ExpressRouteCircuitsClient) (erc ExpressRouteCircuit, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.ExpressRouteCircuitsUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if erc.Response.Response, err = future.GetResult(sender); err == nil && erc.Response.Response.StatusCode != http.StatusNoContent {
		erc, err = client.UpdateTagsResponder(erc.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.ExpressRouteCircuitsUpdateTagsFuture", "Result", erc.Response.Response, "Failure responding to request")
		}
	}
	return
}

// ExpressRouteServiceProvider a ExpressRouteResourceProvider object.
type ExpressRouteServiceProvider struct {
	*ExpressRouteServiceProviderPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for ExpressRouteServiceProvider.
func (ersp ExpressRouteServiceProvider) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ersp.ExpressRouteServiceProviderPropertiesFormat != nil {
		objectMap["properties"] = ersp.ExpressRouteServiceProviderPropertiesFormat
	}
	if ersp.ID != nil {
		objectMap["id"] = ersp.ID
	}
	if ersp.Name != nil {
		objectMap["name"] = ersp.Name
	}
	if ersp.Type != nil {
		objectMap["type"] = ersp.Type
	}
	if ersp.Location != nil {
		objectMap["location"] = ersp.Location
	}
	if ersp.Tags != nil {
		objectMap["tags"] = ersp.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ExpressRouteServiceProvider struct.
func (ersp *ExpressRouteServiceProvider) 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 {
				var expressRouteServiceProviderPropertiesFormat ExpressRouteServiceProviderPropertiesFormat
				err = json.Unmarshal(*v, &expressRouteServiceProviderPropertiesFormat)
				if err != nil {
					return err
				}
				ersp.ExpressRouteServiceProviderPropertiesFormat = &expressRouteServiceProviderPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ersp.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ersp.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				ersp.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				ersp.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				ersp.Tags = tags
			}
		}
	}

	return nil
}

// ExpressRouteServiceProviderBandwidthsOffered contains bandwidths offered in ExpressRouteServiceProvider
// resources.
type ExpressRouteServiceProviderBandwidthsOffered struct {
	// OfferName - The OfferName.
	OfferName *string `json:"offerName,omitempty"`
	// ValueInMbps - The ValueInMbps.
	ValueInMbps *int32 `json:"valueInMbps,omitempty"`
}

// ExpressRouteServiceProviderListResult response for the ListExpressRouteServiceProvider API service call.
type ExpressRouteServiceProviderListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of ExpressRouteResourceProvider resources.
	Value *[]ExpressRouteServiceProvider `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// ExpressRouteServiceProviderListResultIterator provides access to a complete listing of
// ExpressRouteServiceProvider values.
type ExpressRouteServiceProviderListResultIterator struct {
	i    int
	page ExpressRouteServiceProviderListResultPage
}

// 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 *ExpressRouteServiceProviderListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteServiceProviderListResultIterator.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 *ExpressRouteServiceProviderListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter ExpressRouteServiceProviderListResultIterator) 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 ExpressRouteServiceProviderListResultIterator) Response() ExpressRouteServiceProviderListResult {
	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 ExpressRouteServiceProviderListResultIterator) Value() ExpressRouteServiceProvider {
	if !iter.page.NotDone() {
		return ExpressRouteServiceProvider{}
	}
	return iter.page.Values()[iter.i]
}

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

// expressRouteServiceProviderListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (ersplr ExpressRouteServiceProviderListResult) expressRouteServiceProviderListResultPreparer(ctx context.Context) (*http.Request, error) {
	if ersplr.NextLink == nil || len(to.String(ersplr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(ersplr.NextLink)))
}

// ExpressRouteServiceProviderListResultPage contains a page of ExpressRouteServiceProvider values.
type ExpressRouteServiceProviderListResultPage struct {
	fn     func(context.Context, ExpressRouteServiceProviderListResult) (ExpressRouteServiceProviderListResult, error)
	ersplr ExpressRouteServiceProviderListResult
}

// 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 *ExpressRouteServiceProviderListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/ExpressRouteServiceProviderListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.ersplr)
	if err != nil {
		return err
	}
	page.ersplr = next
	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 *ExpressRouteServiceProviderListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page ExpressRouteServiceProviderListResultPage) Response() ExpressRouteServiceProviderListResult {
	return page.ersplr
}

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

// ExpressRouteServiceProviderPropertiesFormat properties of ExpressRouteServiceProvider.
type ExpressRouteServiceProviderPropertiesFormat struct {
	// PeeringLocations - Get a list of peering locations.
	PeeringLocations *[]string `json:"peeringLocations,omitempty"`
	// BandwidthsOffered - Gets bandwidths offered.
	BandwidthsOffered *[]ExpressRouteServiceProviderBandwidthsOffered `json:"bandwidthsOffered,omitempty"`
	// ProvisioningState - Gets the provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// FlowLogInformation information on the configuration of flow log.
type FlowLogInformation struct {
	autorest.Response `json:"-"`
	// TargetResourceID - The ID of the resource to configure for flow logging.
	TargetResourceID   *string `json:"targetResourceId,omitempty"`
	*FlowLogProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for FlowLogInformation.
func (fli FlowLogInformation) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fli.TargetResourceID != nil {
		objectMap["targetResourceId"] = fli.TargetResourceID
	}
	if fli.FlowLogProperties != nil {
		objectMap["properties"] = fli.FlowLogProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for FlowLogInformation struct.
func (fli *FlowLogInformation) 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 "targetResourceId":
			if v != nil {
				var targetResourceID string
				err = json.Unmarshal(*v, &targetResourceID)
				if err != nil {
					return err
				}
				fli.TargetResourceID = &targetResourceID
			}
		case "properties":
			if v != nil {
				var flowLogProperties FlowLogProperties
				err = json.Unmarshal(*v, &flowLogProperties)
				if err != nil {
					return err
				}
				fli.FlowLogProperties = &flowLogProperties
			}
		}
	}

	return nil
}

// FlowLogProperties parameters that define the configuration of flow log.
type FlowLogProperties struct {
	// StorageID - ID of the storage account which is used to store the flow log.
	StorageID *string `json:"storageId,omitempty"`
	// Enabled - Flag to enable/disable flow logging.
	Enabled         *bool                      `json:"enabled,omitempty"`
	RetentionPolicy *RetentionPolicyParameters `json:"retentionPolicy,omitempty"`
}

// FlowLogStatusParameters parameters that define a resource to query flow log status.
type FlowLogStatusParameters struct {
	// TargetResourceID - The target resource where getting the flow logging status.
	TargetResourceID *string `json:"targetResourceId,omitempty"`
}

// FrontendIPConfiguration frontend IP address of the load balancer.
type FrontendIPConfiguration struct {
	autorest.Response `json:"-"`
	// FrontendIPConfigurationPropertiesFormat - Properties of the load balancer probe.
	*FrontendIPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Zones - A list of availability zones denoting the IP allocated for the resource needs to come from.
	Zones *[]string `json:"zones,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for FrontendIPConfiguration.
func (fic FrontendIPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if fic.FrontendIPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = fic.FrontendIPConfigurationPropertiesFormat
	}
	if fic.Name != nil {
		objectMap["name"] = fic.Name
	}
	if fic.Etag != nil {
		objectMap["etag"] = fic.Etag
	}
	if fic.Zones != nil {
		objectMap["zones"] = fic.Zones
	}
	if fic.ID != nil {
		objectMap["id"] = fic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for FrontendIPConfiguration struct.
func (fic *FrontendIPConfiguration) 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 {
				var frontendIPConfigurationPropertiesFormat FrontendIPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &frontendIPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				fic.FrontendIPConfigurationPropertiesFormat = &frontendIPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				fic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				fic.Etag = &etag
			}
		case "zones":
			if v != nil {
				var zones []string
				err = json.Unmarshal(*v, &zones)
				if err != nil {
					return err
				}
				fic.Zones = &zones
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				fic.ID = &ID
			}
		}
	}

	return nil
}

// FrontendIPConfigurationPropertiesFormat properties of Frontend IP Configuration of the load balancer.
type FrontendIPConfigurationPropertiesFormat struct {
	// InboundNatRules - Read only. Inbound rules URIs that use this frontend IP.
	InboundNatRules *[]SubResource `json:"inboundNatRules,omitempty"`
	// InboundNatPools - Read only. Inbound pools URIs that use this frontend IP.
	InboundNatPools *[]SubResource `json:"inboundNatPools,omitempty"`
	// OutboundNatRules - Read only. Outbound rules URIs that use this frontend IP.
	OutboundNatRules *[]SubResource `json:"outboundNatRules,omitempty"`
	// LoadBalancingRules - Gets load balancing rules URIs that use this frontend IP.
	LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"`
	// PrivateIPAddress - The private IP address of the IP configuration.
	PrivateIPAddress *string `json:"privateIPAddress,omitempty"`
	// PrivateIPAllocationMethod - The Private IP allocation method. Possible values are: 'Static' and 'Dynamic'. Possible values include: 'Static', 'Dynamic'
	PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"`
	// Subnet - The reference of the subnet resource.
	Subnet *Subnet `json:"subnet,omitempty"`
	// PublicIPAddress - The reference of the Public IP resource.
	PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// GatewayRoute gateway routing details
type GatewayRoute struct {
	// LocalAddress - The gateway's local address
	LocalAddress *string `json:"localAddress,omitempty"`
	// NetworkProperty - The route's network prefix
	NetworkProperty *string `json:"network,omitempty"`
	// NextHop - The route's next hop
	NextHop *string `json:"nextHop,omitempty"`
	// SourcePeer - The peer this route was learned from
	SourcePeer *string `json:"sourcePeer,omitempty"`
	// Origin - The source this route was learned from
	Origin *string `json:"origin,omitempty"`
	// AsPath - The route's AS path sequence
	AsPath *string `json:"asPath,omitempty"`
	// Weight - The route's weight
	Weight *int32 `json:"weight,omitempty"`
}

// GatewayRouteListResult list of virtual network gateway routes
type GatewayRouteListResult struct {
	autorest.Response `json:"-"`
	// Value - List of gateway routes
	Value *[]GatewayRoute `json:"value,omitempty"`
}

// InboundNatPool inbound NAT pool of the load balancer.
type InboundNatPool struct {
	// InboundNatPoolPropertiesFormat - Properties of load balancer inbound nat pool.
	*InboundNatPoolPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for InboundNatPool.
func (inp InboundNatPool) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if inp.InboundNatPoolPropertiesFormat != nil {
		objectMap["properties"] = inp.InboundNatPoolPropertiesFormat
	}
	if inp.Name != nil {
		objectMap["name"] = inp.Name
	}
	if inp.Etag != nil {
		objectMap["etag"] = inp.Etag
	}
	if inp.ID != nil {
		objectMap["id"] = inp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for InboundNatPool struct.
func (inp *InboundNatPool) 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 {
				var inboundNatPoolPropertiesFormat InboundNatPoolPropertiesFormat
				err = json.Unmarshal(*v, &inboundNatPoolPropertiesFormat)
				if err != nil {
					return err
				}
				inp.InboundNatPoolPropertiesFormat = &inboundNatPoolPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				inp.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				inp.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				inp.ID = &ID
			}
		}
	}

	return nil
}

// InboundNatPoolPropertiesFormat properties of Inbound NAT pool.
type InboundNatPoolPropertiesFormat struct {
	// FrontendIPConfiguration - A reference to frontend IP addresses.
	FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"`
	// Protocol - Possible values include: 'TransportProtocolUDP', 'TransportProtocolTCP', 'TransportProtocolAll'
	Protocol TransportProtocol `json:"protocol,omitempty"`
	// FrontendPortRangeStart - The first port number in the range of external ports that will be used to provide Inbound Nat to NICs associated with a load balancer. Acceptable values range between 1 and 65534.
	FrontendPortRangeStart *int32 `json:"frontendPortRangeStart,omitempty"`
	// FrontendPortRangeEnd - The last port number in the range of external ports that will be used to provide Inbound Nat to NICs associated with a load balancer. Acceptable values range between 1 and 65535.
	FrontendPortRangeEnd *int32 `json:"frontendPortRangeEnd,omitempty"`
	// BackendPort - The port used for internal connections on the endpoint. Acceptable values are between 1 and 65535.
	BackendPort *int32 `json:"backendPort,omitempty"`
	// ProvisioningState - Gets the provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// InboundNatRule inbound NAT rule of the load balancer.
type InboundNatRule struct {
	autorest.Response `json:"-"`
	// InboundNatRulePropertiesFormat - Properties of load balancer inbound nat rule.
	*InboundNatRulePropertiesFormat `json:"properties,omitempty"`
	// Name - Gets name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for InboundNatRule.
func (inr InboundNatRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if inr.InboundNatRulePropertiesFormat != nil {
		objectMap["properties"] = inr.InboundNatRulePropertiesFormat
	}
	if inr.Name != nil {
		objectMap["name"] = inr.Name
	}
	if inr.Etag != nil {
		objectMap["etag"] = inr.Etag
	}
	if inr.ID != nil {
		objectMap["id"] = inr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for InboundNatRule struct.
func (inr *InboundNatRule) 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 {
				var inboundNatRulePropertiesFormat InboundNatRulePropertiesFormat
				err = json.Unmarshal(*v, &inboundNatRulePropertiesFormat)
				if err != nil {
					return err
				}
				inr.InboundNatRulePropertiesFormat = &inboundNatRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				inr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				inr.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				inr.ID = &ID
			}
		}
	}

	return nil
}

// InboundNatRuleListResult response for ListInboundNatRule API service call.
type InboundNatRuleListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of inbound nat rules in a load balancer.
	Value *[]InboundNatRule `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// InboundNatRuleListResultIterator provides access to a complete listing of InboundNatRule values.
type InboundNatRuleListResultIterator struct {
	i    int
	page InboundNatRuleListResultPage
}

// 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 *InboundNatRuleListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InboundNatRuleListResultIterator.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 *InboundNatRuleListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter InboundNatRuleListResultIterator) 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 InboundNatRuleListResultIterator) Response() InboundNatRuleListResult {
	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 InboundNatRuleListResultIterator) Value() InboundNatRule {
	if !iter.page.NotDone() {
		return InboundNatRule{}
	}
	return iter.page.Values()[iter.i]
}

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

// inboundNatRuleListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (inrlr InboundNatRuleListResult) inboundNatRuleListResultPreparer(ctx context.Context) (*http.Request, error) {
	if inrlr.NextLink == nil || len(to.String(inrlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(inrlr.NextLink)))
}

// InboundNatRuleListResultPage contains a page of InboundNatRule values.
type InboundNatRuleListResultPage struct {
	fn    func(context.Context, InboundNatRuleListResult) (InboundNatRuleListResult, error)
	inrlr InboundNatRuleListResult
}

// 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 *InboundNatRuleListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InboundNatRuleListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.inrlr)
	if err != nil {
		return err
	}
	page.inrlr = next
	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 *InboundNatRuleListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page InboundNatRuleListResultPage) Response() InboundNatRuleListResult {
	return page.inrlr
}

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

// InboundNatRulePropertiesFormat properties of the inbound NAT rule.
type InboundNatRulePropertiesFormat struct {
	// FrontendIPConfiguration - A reference to frontend IP addresses.
	FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"`
	// BackendIPConfiguration - A reference to a private IP address defined on a network interface of a VM. Traffic sent to the frontend port of each of the frontend IP configurations is forwarded to the backend IP.
	BackendIPConfiguration *InterfaceIPConfiguration `json:"backendIPConfiguration,omitempty"`
	// Protocol - Possible values include: 'TransportProtocolUDP', 'TransportProtocolTCP', 'TransportProtocolAll'
	Protocol TransportProtocol `json:"protocol,omitempty"`
	// FrontendPort - The port for the external endpoint. Port numbers for each rule must be unique within the Load Balancer. Acceptable values range from 1 to 65534.
	FrontendPort *int32 `json:"frontendPort,omitempty"`
	// BackendPort - The port used for the internal endpoint. Acceptable values range from 1 to 65535.
	BackendPort *int32 `json:"backendPort,omitempty"`
	// IdleTimeoutInMinutes - The timeout for the TCP idle connection. The value can be set between 4 and 30 minutes. The default value is 4 minutes. This element is only used when the protocol is set to TCP.
	IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"`
	// EnableFloatingIP - Configures a virtual machine's endpoint for the floating IP capability required to configure a SQL AlwaysOn Availability Group. This setting is required when using the SQL AlwaysOn Availability Groups in SQL server. This setting can't be changed after you create the endpoint.
	EnableFloatingIP *bool `json:"enableFloatingIP,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// InboundNatRulesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type InboundNatRulesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InboundNatRulesCreateOrUpdateFuture) Result(client InboundNatRulesClient) (inr InboundNatRule, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InboundNatRulesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if inr.Response.Response, err = future.GetResult(sender); err == nil && inr.Response.Response.StatusCode != http.StatusNoContent {
		inr, err = client.CreateOrUpdateResponder(inr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.InboundNatRulesCreateOrUpdateFuture", "Result", inr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// InboundNatRulesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type InboundNatRulesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InboundNatRulesDeleteFuture) Result(client InboundNatRulesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InboundNatRulesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InboundNatRulesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// Interface a network interface in a resource group.
type Interface struct {
	autorest.Response `json:"-"`
	// InterfacePropertiesFormat - Properties of the network interface.
	*InterfacePropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Interface.
func (i Interface) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if i.InterfacePropertiesFormat != nil {
		objectMap["properties"] = i.InterfacePropertiesFormat
	}
	if i.Etag != nil {
		objectMap["etag"] = i.Etag
	}
	if i.ID != nil {
		objectMap["id"] = i.ID
	}
	if i.Name != nil {
		objectMap["name"] = i.Name
	}
	if i.Type != nil {
		objectMap["type"] = i.Type
	}
	if i.Location != nil {
		objectMap["location"] = i.Location
	}
	if i.Tags != nil {
		objectMap["tags"] = i.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Interface struct.
func (i *Interface) 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 {
				var interfacePropertiesFormat InterfacePropertiesFormat
				err = json.Unmarshal(*v, &interfacePropertiesFormat)
				if err != nil {
					return err
				}
				i.InterfacePropertiesFormat = &interfacePropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				i.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				i.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				i.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				i.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				i.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				i.Tags = tags
			}
		}
	}

	return nil
}

// InterfaceAssociation network interface and its custom security rules.
type InterfaceAssociation struct {
	// ID - Network interface ID.
	ID *string `json:"id,omitempty"`
	// SecurityRules - Collection of custom security rules.
	SecurityRules *[]SecurityRule `json:"securityRules,omitempty"`
}

// InterfaceDNSSettings DNS settings of a network interface.
type InterfaceDNSSettings struct {
	// DNSServers - List of DNS servers IP addresses. Use 'AzureProvidedDNS' to switch to azure provided DNS resolution. 'AzureProvidedDNS' value cannot be combined with other IPs, it must be the only value in dnsServers collection.
	DNSServers *[]string `json:"dnsServers,omitempty"`
	// AppliedDNSServers - If the VM that uses this NIC is part of an Availability Set, then this list will have the union of all DNS servers from all NICs that are part of the Availability Set. This property is what is configured on each of those VMs.
	AppliedDNSServers *[]string `json:"appliedDnsServers,omitempty"`
	// InternalDNSNameLabel - Relative DNS name for this NIC used for internal communications between VMs in the same virtual network.
	InternalDNSNameLabel *string `json:"internalDnsNameLabel,omitempty"`
	// InternalFqdn - Fully qualified DNS name supporting internal communications between VMs in the same virtual network.
	InternalFqdn *string `json:"internalFqdn,omitempty"`
	// InternalDomainNameSuffix - Even if internalDnsNameLabel is not specified, a DNS entry is created for the primary NIC of the VM. This DNS name can be constructed by concatenating the VM name with the value of internalDomainNameSuffix.
	InternalDomainNameSuffix *string `json:"internalDomainNameSuffix,omitempty"`
}

// InterfaceIPConfiguration iPConfiguration in a network interface.
type InterfaceIPConfiguration struct {
	autorest.Response `json:"-"`
	// InterfaceIPConfigurationPropertiesFormat - Network interface IP configuration properties.
	*InterfaceIPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for InterfaceIPConfiguration.
func (iic InterfaceIPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if iic.InterfaceIPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = iic.InterfaceIPConfigurationPropertiesFormat
	}
	if iic.Name != nil {
		objectMap["name"] = iic.Name
	}
	if iic.Etag != nil {
		objectMap["etag"] = iic.Etag
	}
	if iic.ID != nil {
		objectMap["id"] = iic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for InterfaceIPConfiguration struct.
func (iic *InterfaceIPConfiguration) 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 {
				var interfaceIPConfigurationPropertiesFormat InterfaceIPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &interfaceIPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				iic.InterfaceIPConfigurationPropertiesFormat = &interfaceIPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				iic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				iic.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				iic.ID = &ID
			}
		}
	}

	return nil
}

// InterfaceIPConfigurationListResult response for list ip configurations API service call.
type InterfaceIPConfigurationListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of ip configurations.
	Value *[]InterfaceIPConfiguration `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// InterfaceIPConfigurationListResultIterator provides access to a complete listing of
// InterfaceIPConfiguration values.
type InterfaceIPConfigurationListResultIterator struct {
	i    int
	page InterfaceIPConfigurationListResultPage
}

// 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 *InterfaceIPConfigurationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceIPConfigurationListResultIterator.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 *InterfaceIPConfigurationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter InterfaceIPConfigurationListResultIterator) 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 InterfaceIPConfigurationListResultIterator) Response() InterfaceIPConfigurationListResult {
	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 InterfaceIPConfigurationListResultIterator) Value() InterfaceIPConfiguration {
	if !iter.page.NotDone() {
		return InterfaceIPConfiguration{}
	}
	return iter.page.Values()[iter.i]
}

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

// interfaceIPConfigurationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (iiclr InterfaceIPConfigurationListResult) interfaceIPConfigurationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if iiclr.NextLink == nil || len(to.String(iiclr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(iiclr.NextLink)))
}

// InterfaceIPConfigurationListResultPage contains a page of InterfaceIPConfiguration values.
type InterfaceIPConfigurationListResultPage struct {
	fn    func(context.Context, InterfaceIPConfigurationListResult) (InterfaceIPConfigurationListResult, error)
	iiclr InterfaceIPConfigurationListResult
}

// 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 *InterfaceIPConfigurationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceIPConfigurationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.iiclr)
	if err != nil {
		return err
	}
	page.iiclr = next
	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 *InterfaceIPConfigurationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page InterfaceIPConfigurationListResultPage) Response() InterfaceIPConfigurationListResult {
	return page.iiclr
}

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

// InterfaceIPConfigurationPropertiesFormat properties of IP configuration.
type InterfaceIPConfigurationPropertiesFormat struct {
	// ApplicationGatewayBackendAddressPools - The reference of ApplicationGatewayBackendAddressPool resource.
	ApplicationGatewayBackendAddressPools *[]ApplicationGatewayBackendAddressPool `json:"applicationGatewayBackendAddressPools,omitempty"`
	// LoadBalancerBackendAddressPools - The reference of LoadBalancerBackendAddressPool resource.
	LoadBalancerBackendAddressPools *[]BackendAddressPool `json:"loadBalancerBackendAddressPools,omitempty"`
	// LoadBalancerInboundNatRules - A list of references of LoadBalancerInboundNatRules.
	LoadBalancerInboundNatRules *[]InboundNatRule `json:"loadBalancerInboundNatRules,omitempty"`
	// PrivateIPAddress - Private IP address of the IP configuration.
	PrivateIPAddress *string `json:"privateIPAddress,omitempty"`
	// PrivateIPAllocationMethod - Defines how a private IP address is assigned. Possible values are: 'Static' and 'Dynamic'. Possible values include: 'Static', 'Dynamic'
	PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"`
	// PrivateIPAddressVersion - Available from Api-Version 2016-03-30 onwards, it represents whether the specific ipconfiguration is IPv4 or IPv6. Default is taken as IPv4.  Possible values are: 'IPv4' and 'IPv6'. Possible values include: 'IPv4', 'IPv6'
	PrivateIPAddressVersion IPVersion `json:"privateIPAddressVersion,omitempty"`
	// Subnet - Subnet bound to the IP configuration.
	Subnet *Subnet `json:"subnet,omitempty"`
	// Primary - Gets whether this is a primary customer address on the network interface.
	Primary *bool `json:"primary,omitempty"`
	// PublicIPAddress - Public IP address bound to the IP configuration.
	PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"`
	// ApplicationSecurityGroups - Application security groups in which the IP configuration is included.
	ApplicationSecurityGroups *[]ApplicationSecurityGroup `json:"applicationSecurityGroups,omitempty"`
	// ProvisioningState - The provisioning state of the network interface IP configuration. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// InterfaceListResult response for the ListNetworkInterface API service call.
type InterfaceListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of network interfaces in a resource group.
	Value *[]Interface `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// InterfaceListResultIterator provides access to a complete listing of Interface values.
type InterfaceListResultIterator struct {
	i    int
	page InterfaceListResultPage
}

// 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 *InterfaceListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceListResultIterator.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 *InterfaceListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter InterfaceListResultIterator) 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 InterfaceListResultIterator) Response() InterfaceListResult {
	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 InterfaceListResultIterator) Value() Interface {
	if !iter.page.NotDone() {
		return Interface{}
	}
	return iter.page.Values()[iter.i]
}

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

// interfaceListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (ilr InterfaceListResult) interfaceListResultPreparer(ctx context.Context) (*http.Request, error) {
	if ilr.NextLink == nil || len(to.String(ilr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(ilr.NextLink)))
}

// InterfaceListResultPage contains a page of Interface values.
type InterfaceListResultPage struct {
	fn  func(context.Context, InterfaceListResult) (InterfaceListResult, error)
	ilr InterfaceListResult
}

// 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 *InterfaceListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.ilr)
	if err != nil {
		return err
	}
	page.ilr = next
	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 *InterfaceListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page InterfaceListResultPage) Response() InterfaceListResult {
	return page.ilr
}

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

// InterfaceLoadBalancerListResult response for list ip configurations API service call.
type InterfaceLoadBalancerListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of load balancers.
	Value *[]LoadBalancer `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// InterfaceLoadBalancerListResultIterator provides access to a complete listing of LoadBalancer values.
type InterfaceLoadBalancerListResultIterator struct {
	i    int
	page InterfaceLoadBalancerListResultPage
}

// 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 *InterfaceLoadBalancerListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceLoadBalancerListResultIterator.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 *InterfaceLoadBalancerListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter InterfaceLoadBalancerListResultIterator) 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 InterfaceLoadBalancerListResultIterator) Response() InterfaceLoadBalancerListResult {
	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 InterfaceLoadBalancerListResultIterator) Value() LoadBalancer {
	if !iter.page.NotDone() {
		return LoadBalancer{}
	}
	return iter.page.Values()[iter.i]
}

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

// interfaceLoadBalancerListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (ilblr InterfaceLoadBalancerListResult) interfaceLoadBalancerListResultPreparer(ctx context.Context) (*http.Request, error) {
	if ilblr.NextLink == nil || len(to.String(ilblr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(ilblr.NextLink)))
}

// InterfaceLoadBalancerListResultPage contains a page of LoadBalancer values.
type InterfaceLoadBalancerListResultPage struct {
	fn    func(context.Context, InterfaceLoadBalancerListResult) (InterfaceLoadBalancerListResult, error)
	ilblr InterfaceLoadBalancerListResult
}

// 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 *InterfaceLoadBalancerListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/InterfaceLoadBalancerListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.ilblr)
	if err != nil {
		return err
	}
	page.ilblr = next
	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 *InterfaceLoadBalancerListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page InterfaceLoadBalancerListResultPage) Response() InterfaceLoadBalancerListResult {
	return page.ilblr
}

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

// InterfacePropertiesFormat networkInterface properties.
type InterfacePropertiesFormat struct {
	// VirtualMachine - The reference of a virtual machine.
	VirtualMachine *SubResource `json:"virtualMachine,omitempty"`
	// NetworkSecurityGroup - The reference of the NetworkSecurityGroup resource.
	NetworkSecurityGroup *SecurityGroup `json:"networkSecurityGroup,omitempty"`
	// IPConfigurations - A list of IPConfigurations of the network interface.
	IPConfigurations *[]InterfaceIPConfiguration `json:"ipConfigurations,omitempty"`
	// DNSSettings - The DNS settings in network interface.
	DNSSettings *InterfaceDNSSettings `json:"dnsSettings,omitempty"`
	// MacAddress - The MAC address of the network interface.
	MacAddress *string `json:"macAddress,omitempty"`
	// Primary - Gets whether this is a primary network interface on a virtual machine.
	Primary *bool `json:"primary,omitempty"`
	// EnableAcceleratedNetworking - If the network interface is accelerated networking enabled.
	EnableAcceleratedNetworking *bool `json:"enableAcceleratedNetworking,omitempty"`
	// EnableIPForwarding - Indicates whether IP forwarding is enabled on this network interface.
	EnableIPForwarding *bool `json:"enableIPForwarding,omitempty"`
	// ResourceGUID - The resource GUID property of the network interface resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// InterfacesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type InterfacesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InterfacesCreateOrUpdateFuture) Result(client InterfacesClient) (i Interface, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InterfacesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent {
		i, err = client.CreateOrUpdateResponder(i.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.InterfacesCreateOrUpdateFuture", "Result", i.Response.Response, "Failure responding to request")
		}
	}
	return
}

// InterfacesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type InterfacesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InterfacesDeleteFuture) Result(client InterfacesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InterfacesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InterfacesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// InterfacesGetEffectiveRouteTableFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type InterfacesGetEffectiveRouteTableFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InterfacesGetEffectiveRouteTableFuture) Result(client InterfacesClient) (erlr EffectiveRouteListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InterfacesGetEffectiveRouteTableFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if erlr.Response.Response, err = future.GetResult(sender); err == nil && erlr.Response.Response.StatusCode != http.StatusNoContent {
		erlr, err = client.GetEffectiveRouteTableResponder(erlr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.InterfacesGetEffectiveRouteTableFuture", "Result", erlr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// InterfacesListEffectiveNetworkSecurityGroupsFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type InterfacesListEffectiveNetworkSecurityGroupsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InterfacesListEffectiveNetworkSecurityGroupsFuture) Result(client InterfacesClient) (ensglr EffectiveNetworkSecurityGroupListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InterfacesListEffectiveNetworkSecurityGroupsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ensglr.Response.Response, err = future.GetResult(sender); err == nil && ensglr.Response.Response.StatusCode != http.StatusNoContent {
		ensglr, err = client.ListEffectiveNetworkSecurityGroupsResponder(ensglr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.InterfacesListEffectiveNetworkSecurityGroupsFuture", "Result", ensglr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// InterfacesUpdateTagsFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type InterfacesUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *InterfacesUpdateTagsFuture) Result(client InterfacesClient) (i Interface, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.InterfacesUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if i.Response.Response, err = future.GetResult(sender); err == nil && i.Response.Response.StatusCode != http.StatusNoContent {
		i, err = client.UpdateTagsResponder(i.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.InterfacesUpdateTagsFuture", "Result", i.Response.Response, "Failure responding to request")
		}
	}
	return
}

// IPAddressAvailabilityResult response for CheckIPAddressAvailability API service call
type IPAddressAvailabilityResult struct {
	autorest.Response `json:"-"`
	// Available - Private IP address availability.
	Available *bool `json:"available,omitempty"`
	// AvailableIPAddresses - Contains other available private IP addresses if the asked for address is taken.
	AvailableIPAddresses *[]string `json:"availableIPAddresses,omitempty"`
}

// IPConfiguration IP configuration
type IPConfiguration struct {
	// IPConfigurationPropertiesFormat - Properties of the IP configuration
	*IPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for IPConfiguration.
func (ic IPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if ic.IPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = ic.IPConfigurationPropertiesFormat
	}
	if ic.Name != nil {
		objectMap["name"] = ic.Name
	}
	if ic.Etag != nil {
		objectMap["etag"] = ic.Etag
	}
	if ic.ID != nil {
		objectMap["id"] = ic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for IPConfiguration struct.
func (ic *IPConfiguration) 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 {
				var IPConfigurationPropertiesFormat IPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &IPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				ic.IPConfigurationPropertiesFormat = &IPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				ic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				ic.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				ic.ID = &ID
			}
		}
	}

	return nil
}

// IPConfigurationPropertiesFormat properties of IP configuration.
type IPConfigurationPropertiesFormat struct {
	// PrivateIPAddress - The private IP address of the IP configuration.
	PrivateIPAddress *string `json:"privateIPAddress,omitempty"`
	// PrivateIPAllocationMethod - The private IP allocation method. Possible values are 'Static' and 'Dynamic'. Possible values include: 'Static', 'Dynamic'
	PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"`
	// Subnet - The reference of the subnet resource.
	Subnet *Subnet `json:"subnet,omitempty"`
	// PublicIPAddress - The reference of the public IP resource.
	PublicIPAddress *PublicIPAddress `json:"publicIPAddress,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// IpsecPolicy an IPSec Policy configuration for a virtual network gateway connection
type IpsecPolicy struct {
	// SaLifeTimeSeconds - The IPSec Security Association (also called Quick Mode or Phase 2 SA) lifetime in seconds for a site to site VPN tunnel.
	SaLifeTimeSeconds *int32 `json:"saLifeTimeSeconds,omitempty"`
	// SaDataSizeKilobytes - The IPSec Security Association (also called Quick Mode or Phase 2 SA) payload size in KB for a site to site VPN tunnel.
	SaDataSizeKilobytes *int32 `json:"saDataSizeKilobytes,omitempty"`
	// IpsecEncryption - The IPSec encryption algorithm (IKE phase 1). Possible values include: 'IpsecEncryptionNone', 'IpsecEncryptionDES', 'IpsecEncryptionDES3', 'IpsecEncryptionAES128', 'IpsecEncryptionAES192', 'IpsecEncryptionAES256', 'IpsecEncryptionGCMAES128', 'IpsecEncryptionGCMAES192', 'IpsecEncryptionGCMAES256'
	IpsecEncryption IpsecEncryption `json:"ipsecEncryption,omitempty"`
	// IpsecIntegrity - The IPSec integrity algorithm (IKE phase 1). Possible values include: 'IpsecIntegrityMD5', 'IpsecIntegritySHA1', 'IpsecIntegritySHA256', 'IpsecIntegrityGCMAES128', 'IpsecIntegrityGCMAES192', 'IpsecIntegrityGCMAES256'
	IpsecIntegrity IpsecIntegrity `json:"ipsecIntegrity,omitempty"`
	// IkeEncryption - The IKE encryption algorithm (IKE phase 2). Possible values include: 'DES', 'DES3', 'AES128', 'AES192', 'AES256'
	IkeEncryption IkeEncryption `json:"ikeEncryption,omitempty"`
	// IkeIntegrity - The IKE integrity algorithm (IKE phase 2). Possible values include: 'MD5', 'SHA1', 'SHA256', 'SHA384'
	IkeIntegrity IkeIntegrity `json:"ikeIntegrity,omitempty"`
	// DhGroup - The DH Groups used in IKE Phase 1 for initial SA. Possible values include: 'None', 'DHGroup1', 'DHGroup2', 'DHGroup14', 'DHGroup2048', 'ECP256', 'ECP384', 'DHGroup24'
	DhGroup DhGroup `json:"dhGroup,omitempty"`
	// PfsGroup - The DH Groups used in IKE Phase 2 for new child SA. Possible values include: 'PfsGroupNone', 'PfsGroupPFS1', 'PfsGroupPFS2', 'PfsGroupPFS2048', 'PfsGroupECP256', 'PfsGroupECP384', 'PfsGroupPFS24'
	PfsGroup PfsGroup `json:"pfsGroup,omitempty"`
}

// Ipv6ExpressRouteCircuitPeeringConfig contains IPv6 peering config.
type Ipv6ExpressRouteCircuitPeeringConfig struct {
	// PrimaryPeerAddressPrefix - The primary address prefix.
	PrimaryPeerAddressPrefix *string `json:"primaryPeerAddressPrefix,omitempty"`
	// SecondaryPeerAddressPrefix - The secondary address prefix.
	SecondaryPeerAddressPrefix *string `json:"secondaryPeerAddressPrefix,omitempty"`
	// MicrosoftPeeringConfig - The Microsoft peering configuration.
	MicrosoftPeeringConfig *ExpressRouteCircuitPeeringConfig `json:"microsoftPeeringConfig,omitempty"`
	// RouteFilter - The reference of the RouteFilter resource.
	RouteFilter *RouteFilter `json:"routeFilter,omitempty"`
	// State - The state of peering. Possible values are: 'Disabled' and 'Enabled'. Possible values include: 'ExpressRouteCircuitPeeringStateDisabled', 'ExpressRouteCircuitPeeringStateEnabled'
	State ExpressRouteCircuitPeeringState `json:"state,omitempty"`
}

// LoadBalancer loadBalancer resource
type LoadBalancer struct {
	autorest.Response `json:"-"`
	// Sku - The load balancer SKU.
	Sku *LoadBalancerSku `json:"sku,omitempty"`
	// LoadBalancerPropertiesFormat - Properties of load balancer.
	*LoadBalancerPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for LoadBalancer.
func (lb LoadBalancer) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if lb.Sku != nil {
		objectMap["sku"] = lb.Sku
	}
	if lb.LoadBalancerPropertiesFormat != nil {
		objectMap["properties"] = lb.LoadBalancerPropertiesFormat
	}
	if lb.Etag != nil {
		objectMap["etag"] = lb.Etag
	}
	if lb.ID != nil {
		objectMap["id"] = lb.ID
	}
	if lb.Name != nil {
		objectMap["name"] = lb.Name
	}
	if lb.Type != nil {
		objectMap["type"] = lb.Type
	}
	if lb.Location != nil {
		objectMap["location"] = lb.Location
	}
	if lb.Tags != nil {
		objectMap["tags"] = lb.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for LoadBalancer struct.
func (lb *LoadBalancer) 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 "sku":
			if v != nil {
				var sku LoadBalancerSku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				lb.Sku = &sku
			}
		case "properties":
			if v != nil {
				var loadBalancerPropertiesFormat LoadBalancerPropertiesFormat
				err = json.Unmarshal(*v, &loadBalancerPropertiesFormat)
				if err != nil {
					return err
				}
				lb.LoadBalancerPropertiesFormat = &loadBalancerPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				lb.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				lb.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				lb.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				lb.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				lb.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				lb.Tags = tags
			}
		}
	}

	return nil
}

// LoadBalancerBackendAddressPoolListResult response for ListBackendAddressPool API service call.
type LoadBalancerBackendAddressPoolListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of backend address pools in a load balancer.
	Value *[]BackendAddressPool `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LoadBalancerBackendAddressPoolListResultIterator provides access to a complete listing of
// BackendAddressPool values.
type LoadBalancerBackendAddressPoolListResultIterator struct {
	i    int
	page LoadBalancerBackendAddressPoolListResultPage
}

// 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 *LoadBalancerBackendAddressPoolListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerBackendAddressPoolListResultIterator.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 *LoadBalancerBackendAddressPoolListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LoadBalancerBackendAddressPoolListResultIterator) 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 LoadBalancerBackendAddressPoolListResultIterator) Response() LoadBalancerBackendAddressPoolListResult {
	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 LoadBalancerBackendAddressPoolListResultIterator) Value() BackendAddressPool {
	if !iter.page.NotDone() {
		return BackendAddressPool{}
	}
	return iter.page.Values()[iter.i]
}

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

// loadBalancerBackendAddressPoolListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lbbaplr LoadBalancerBackendAddressPoolListResult) loadBalancerBackendAddressPoolListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lbbaplr.NextLink == nil || len(to.String(lbbaplr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lbbaplr.NextLink)))
}

// LoadBalancerBackendAddressPoolListResultPage contains a page of BackendAddressPool values.
type LoadBalancerBackendAddressPoolListResultPage struct {
	fn      func(context.Context, LoadBalancerBackendAddressPoolListResult) (LoadBalancerBackendAddressPoolListResult, error)
	lbbaplr LoadBalancerBackendAddressPoolListResult
}

// 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 *LoadBalancerBackendAddressPoolListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerBackendAddressPoolListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lbbaplr)
	if err != nil {
		return err
	}
	page.lbbaplr = next
	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 *LoadBalancerBackendAddressPoolListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LoadBalancerBackendAddressPoolListResultPage) Response() LoadBalancerBackendAddressPoolListResult {
	return page.lbbaplr
}

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

// LoadBalancerFrontendIPConfigurationListResult response for ListFrontendIPConfiguration API service call.
type LoadBalancerFrontendIPConfigurationListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of frontend IP configurations in a load balancer.
	Value *[]FrontendIPConfiguration `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LoadBalancerFrontendIPConfigurationListResultIterator provides access to a complete listing of
// FrontendIPConfiguration values.
type LoadBalancerFrontendIPConfigurationListResultIterator struct {
	i    int
	page LoadBalancerFrontendIPConfigurationListResultPage
}

// 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 *LoadBalancerFrontendIPConfigurationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerFrontendIPConfigurationListResultIterator.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 *LoadBalancerFrontendIPConfigurationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LoadBalancerFrontendIPConfigurationListResultIterator) 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 LoadBalancerFrontendIPConfigurationListResultIterator) Response() LoadBalancerFrontendIPConfigurationListResult {
	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 LoadBalancerFrontendIPConfigurationListResultIterator) Value() FrontendIPConfiguration {
	if !iter.page.NotDone() {
		return FrontendIPConfiguration{}
	}
	return iter.page.Values()[iter.i]
}

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

// loadBalancerFrontendIPConfigurationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lbficlr LoadBalancerFrontendIPConfigurationListResult) loadBalancerFrontendIPConfigurationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lbficlr.NextLink == nil || len(to.String(lbficlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lbficlr.NextLink)))
}

// LoadBalancerFrontendIPConfigurationListResultPage contains a page of FrontendIPConfiguration values.
type LoadBalancerFrontendIPConfigurationListResultPage struct {
	fn      func(context.Context, LoadBalancerFrontendIPConfigurationListResult) (LoadBalancerFrontendIPConfigurationListResult, error)
	lbficlr LoadBalancerFrontendIPConfigurationListResult
}

// 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 *LoadBalancerFrontendIPConfigurationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerFrontendIPConfigurationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lbficlr)
	if err != nil {
		return err
	}
	page.lbficlr = next
	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 *LoadBalancerFrontendIPConfigurationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LoadBalancerFrontendIPConfigurationListResultPage) Response() LoadBalancerFrontendIPConfigurationListResult {
	return page.lbficlr
}

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

// LoadBalancerListResult response for ListLoadBalancers API service call.
type LoadBalancerListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of load balancers in a resource group.
	Value *[]LoadBalancer `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LoadBalancerListResultIterator provides access to a complete listing of LoadBalancer values.
type LoadBalancerListResultIterator struct {
	i    int
	page LoadBalancerListResultPage
}

// 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 *LoadBalancerListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerListResultIterator.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 *LoadBalancerListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LoadBalancerListResultIterator) 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 LoadBalancerListResultIterator) Response() LoadBalancerListResult {
	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 LoadBalancerListResultIterator) Value() LoadBalancer {
	if !iter.page.NotDone() {
		return LoadBalancer{}
	}
	return iter.page.Values()[iter.i]
}

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

// loadBalancerListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lblr LoadBalancerListResult) loadBalancerListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lblr.NextLink == nil || len(to.String(lblr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lblr.NextLink)))
}

// LoadBalancerListResultPage contains a page of LoadBalancer values.
type LoadBalancerListResultPage struct {
	fn   func(context.Context, LoadBalancerListResult) (LoadBalancerListResult, error)
	lblr LoadBalancerListResult
}

// 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 *LoadBalancerListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lblr)
	if err != nil {
		return err
	}
	page.lblr = next
	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 *LoadBalancerListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LoadBalancerListResultPage) Response() LoadBalancerListResult {
	return page.lblr
}

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

// LoadBalancerLoadBalancingRuleListResult response for ListLoadBalancingRule API service call.
type LoadBalancerLoadBalancingRuleListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of load balancing rules in a load balancer.
	Value *[]LoadBalancingRule `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LoadBalancerLoadBalancingRuleListResultIterator provides access to a complete listing of
// LoadBalancingRule values.
type LoadBalancerLoadBalancingRuleListResultIterator struct {
	i    int
	page LoadBalancerLoadBalancingRuleListResultPage
}

// 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 *LoadBalancerLoadBalancingRuleListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerLoadBalancingRuleListResultIterator.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 *LoadBalancerLoadBalancingRuleListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LoadBalancerLoadBalancingRuleListResultIterator) 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 LoadBalancerLoadBalancingRuleListResultIterator) Response() LoadBalancerLoadBalancingRuleListResult {
	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 LoadBalancerLoadBalancingRuleListResultIterator) Value() LoadBalancingRule {
	if !iter.page.NotDone() {
		return LoadBalancingRule{}
	}
	return iter.page.Values()[iter.i]
}

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

// loadBalancerLoadBalancingRuleListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lblbrlr LoadBalancerLoadBalancingRuleListResult) loadBalancerLoadBalancingRuleListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lblbrlr.NextLink == nil || len(to.String(lblbrlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lblbrlr.NextLink)))
}

// LoadBalancerLoadBalancingRuleListResultPage contains a page of LoadBalancingRule values.
type LoadBalancerLoadBalancingRuleListResultPage struct {
	fn      func(context.Context, LoadBalancerLoadBalancingRuleListResult) (LoadBalancerLoadBalancingRuleListResult, error)
	lblbrlr LoadBalancerLoadBalancingRuleListResult
}

// 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 *LoadBalancerLoadBalancingRuleListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerLoadBalancingRuleListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lblbrlr)
	if err != nil {
		return err
	}
	page.lblbrlr = next
	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 *LoadBalancerLoadBalancingRuleListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LoadBalancerLoadBalancingRuleListResultPage) Response() LoadBalancerLoadBalancingRuleListResult {
	return page.lblbrlr
}

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

// LoadBalancerProbeListResult response for ListProbe API service call.
type LoadBalancerProbeListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of probes in a load balancer.
	Value *[]Probe `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LoadBalancerProbeListResultIterator provides access to a complete listing of Probe values.
type LoadBalancerProbeListResultIterator struct {
	i    int
	page LoadBalancerProbeListResultPage
}

// 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 *LoadBalancerProbeListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerProbeListResultIterator.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 *LoadBalancerProbeListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LoadBalancerProbeListResultIterator) 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 LoadBalancerProbeListResultIterator) Response() LoadBalancerProbeListResult {
	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 LoadBalancerProbeListResultIterator) Value() Probe {
	if !iter.page.NotDone() {
		return Probe{}
	}
	return iter.page.Values()[iter.i]
}

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

// loadBalancerProbeListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lbplr LoadBalancerProbeListResult) loadBalancerProbeListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lbplr.NextLink == nil || len(to.String(lbplr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lbplr.NextLink)))
}

// LoadBalancerProbeListResultPage contains a page of Probe values.
type LoadBalancerProbeListResultPage struct {
	fn    func(context.Context, LoadBalancerProbeListResult) (LoadBalancerProbeListResult, error)
	lbplr LoadBalancerProbeListResult
}

// 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 *LoadBalancerProbeListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LoadBalancerProbeListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lbplr)
	if err != nil {
		return err
	}
	page.lbplr = next
	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 *LoadBalancerProbeListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LoadBalancerProbeListResultPage) Response() LoadBalancerProbeListResult {
	return page.lbplr
}

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

// LoadBalancerPropertiesFormat properties of the load balancer.
type LoadBalancerPropertiesFormat struct {
	// FrontendIPConfigurations - Object representing the frontend IPs to be used for the load balancer
	FrontendIPConfigurations *[]FrontendIPConfiguration `json:"frontendIPConfigurations,omitempty"`
	// BackendAddressPools - Collection of backend address pools used by a load balancer
	BackendAddressPools *[]BackendAddressPool `json:"backendAddressPools,omitempty"`
	// LoadBalancingRules - Object collection representing the load balancing rules Gets the provisioning
	LoadBalancingRules *[]LoadBalancingRule `json:"loadBalancingRules,omitempty"`
	// Probes - Collection of probe objects used in the load balancer
	Probes *[]Probe `json:"probes,omitempty"`
	// InboundNatRules - Collection of inbound NAT Rules used by a load balancer. Defining inbound NAT rules on your load balancer is mutually exclusive with defining an inbound NAT pool. Inbound NAT pools are referenced from virtual machine scale sets. NICs that are associated with individual virtual machines cannot reference an Inbound NAT pool. They have to reference individual inbound NAT rules.
	InboundNatRules *[]InboundNatRule `json:"inboundNatRules,omitempty"`
	// InboundNatPools - Defines an external port range for inbound NAT to a single backend port on NICs associated with a load balancer. Inbound NAT rules are created automatically for each NIC associated with the Load Balancer using an external port from this range. Defining an Inbound NAT pool on your Load Balancer is mutually exclusive with defining inbound Nat rules. Inbound NAT pools are referenced from virtual machine scale sets. NICs that are associated with individual virtual machines cannot reference an inbound NAT pool. They have to reference individual inbound NAT rules.
	InboundNatPools *[]InboundNatPool `json:"inboundNatPools,omitempty"`
	// OutboundNatRules - The outbound NAT rules.
	OutboundNatRules *[]OutboundNatRule `json:"outboundNatRules,omitempty"`
	// ResourceGUID - The resource GUID property of the load balancer resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - Gets the provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// LoadBalancersCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type LoadBalancersCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LoadBalancersCreateOrUpdateFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LoadBalancersCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if lb.Response.Response, err = future.GetResult(sender); err == nil && lb.Response.Response.StatusCode != http.StatusNoContent {
		lb, err = client.CreateOrUpdateResponder(lb.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.LoadBalancersCreateOrUpdateFuture", "Result", lb.Response.Response, "Failure responding to request")
		}
	}
	return
}

// LoadBalancersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type LoadBalancersDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LoadBalancersDeleteFuture) Result(client LoadBalancersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LoadBalancersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LoadBalancersDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// LoadBalancerSku SKU of a load balancer
type LoadBalancerSku struct {
	// Name - Name of a load balancer SKU. Possible values include: 'LoadBalancerSkuNameBasic', 'LoadBalancerSkuNameStandard'
	Name LoadBalancerSkuName `json:"name,omitempty"`
}

// LoadBalancersUpdateTagsFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type LoadBalancersUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LoadBalancersUpdateTagsFuture) Result(client LoadBalancersClient) (lb LoadBalancer, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LoadBalancersUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if lb.Response.Response, err = future.GetResult(sender); err == nil && lb.Response.Response.StatusCode != http.StatusNoContent {
		lb, err = client.UpdateTagsResponder(lb.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.LoadBalancersUpdateTagsFuture", "Result", lb.Response.Response, "Failure responding to request")
		}
	}
	return
}

// LoadBalancingRule a load balancing rule for a load balancer.
type LoadBalancingRule struct {
	autorest.Response `json:"-"`
	// LoadBalancingRulePropertiesFormat - Properties of load balancer load balancing rule.
	*LoadBalancingRulePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for LoadBalancingRule.
func (lbr LoadBalancingRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if lbr.LoadBalancingRulePropertiesFormat != nil {
		objectMap["properties"] = lbr.LoadBalancingRulePropertiesFormat
	}
	if lbr.Name != nil {
		objectMap["name"] = lbr.Name
	}
	if lbr.Etag != nil {
		objectMap["etag"] = lbr.Etag
	}
	if lbr.ID != nil {
		objectMap["id"] = lbr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for LoadBalancingRule struct.
func (lbr *LoadBalancingRule) 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 {
				var loadBalancingRulePropertiesFormat LoadBalancingRulePropertiesFormat
				err = json.Unmarshal(*v, &loadBalancingRulePropertiesFormat)
				if err != nil {
					return err
				}
				lbr.LoadBalancingRulePropertiesFormat = &loadBalancingRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				lbr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				lbr.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				lbr.ID = &ID
			}
		}
	}

	return nil
}

// LoadBalancingRulePropertiesFormat properties of the load balancer.
type LoadBalancingRulePropertiesFormat struct {
	// FrontendIPConfiguration - A reference to frontend IP addresses.
	FrontendIPConfiguration *SubResource `json:"frontendIPConfiguration,omitempty"`
	// BackendAddressPool - A reference to a pool of DIPs. Inbound traffic is randomly load balanced across IPs in the backend IPs.
	BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"`
	// Probe - The reference of the load balancer probe used by the load balancing rule.
	Probe *SubResource `json:"probe,omitempty"`
	// Protocol - Possible values include: 'TransportProtocolUDP', 'TransportProtocolTCP', 'TransportProtocolAll'
	Protocol TransportProtocol `json:"protocol,omitempty"`
	// LoadDistribution - The load distribution policy for this rule. Possible values are 'Default', 'SourceIP', and 'SourceIPProtocol'. Possible values include: 'Default', 'SourceIP', 'SourceIPProtocol'
	LoadDistribution LoadDistribution `json:"loadDistribution,omitempty"`
	// FrontendPort - The port for the external endpoint. Port numbers for each rule must be unique within the Load Balancer. Acceptable values are between 0 and 65534. Note that value 0 enables "Any Port"
	FrontendPort *int32 `json:"frontendPort,omitempty"`
	// BackendPort - The port used for internal connections on the endpoint. Acceptable values are between 0 and 65535. Note that value 0 enables "Any Port"
	BackendPort *int32 `json:"backendPort,omitempty"`
	// IdleTimeoutInMinutes - The timeout for the TCP idle connection. The value can be set between 4 and 30 minutes. The default value is 4 minutes. This element is only used when the protocol is set to TCP.
	IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"`
	// EnableFloatingIP - Configures a virtual machine's endpoint for the floating IP capability required to configure a SQL AlwaysOn Availability Group. This setting is required when using the SQL AlwaysOn Availability Groups in SQL server. This setting can't be changed after you create the endpoint.
	EnableFloatingIP *bool `json:"enableFloatingIP,omitempty"`
	// DisableOutboundSnat - Configures SNAT for the VMs in the backend pool to use the publicIP address specified in the frontend of the load balancing rule.
	DisableOutboundSnat *bool `json:"disableOutboundSnat,omitempty"`
	// ProvisioningState - Gets the provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// LocalNetworkGateway a common class for general resource information
type LocalNetworkGateway struct {
	autorest.Response `json:"-"`
	// LocalNetworkGatewayPropertiesFormat - Properties of the local network gateway.
	*LocalNetworkGatewayPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for LocalNetworkGateway.
func (lng LocalNetworkGateway) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if lng.LocalNetworkGatewayPropertiesFormat != nil {
		objectMap["properties"] = lng.LocalNetworkGatewayPropertiesFormat
	}
	if lng.Etag != nil {
		objectMap["etag"] = lng.Etag
	}
	if lng.ID != nil {
		objectMap["id"] = lng.ID
	}
	if lng.Name != nil {
		objectMap["name"] = lng.Name
	}
	if lng.Type != nil {
		objectMap["type"] = lng.Type
	}
	if lng.Location != nil {
		objectMap["location"] = lng.Location
	}
	if lng.Tags != nil {
		objectMap["tags"] = lng.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for LocalNetworkGateway struct.
func (lng *LocalNetworkGateway) 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 {
				var localNetworkGatewayPropertiesFormat LocalNetworkGatewayPropertiesFormat
				err = json.Unmarshal(*v, &localNetworkGatewayPropertiesFormat)
				if err != nil {
					return err
				}
				lng.LocalNetworkGatewayPropertiesFormat = &localNetworkGatewayPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				lng.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				lng.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				lng.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				lng.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				lng.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				lng.Tags = tags
			}
		}
	}

	return nil
}

// LocalNetworkGatewayListResult response for ListLocalNetworkGateways API service call.
type LocalNetworkGatewayListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of local network gateways that exists in a resource group.
	Value *[]LocalNetworkGateway `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// LocalNetworkGatewayListResultIterator provides access to a complete listing of LocalNetworkGateway
// values.
type LocalNetworkGatewayListResultIterator struct {
	i    int
	page LocalNetworkGatewayListResultPage
}

// 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 *LocalNetworkGatewayListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LocalNetworkGatewayListResultIterator.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 *LocalNetworkGatewayListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter LocalNetworkGatewayListResultIterator) 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 LocalNetworkGatewayListResultIterator) Response() LocalNetworkGatewayListResult {
	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 LocalNetworkGatewayListResultIterator) Value() LocalNetworkGateway {
	if !iter.page.NotDone() {
		return LocalNetworkGateway{}
	}
	return iter.page.Values()[iter.i]
}

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

// localNetworkGatewayListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (lnglr LocalNetworkGatewayListResult) localNetworkGatewayListResultPreparer(ctx context.Context) (*http.Request, error) {
	if lnglr.NextLink == nil || len(to.String(lnglr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(lnglr.NextLink)))
}

// LocalNetworkGatewayListResultPage contains a page of LocalNetworkGateway values.
type LocalNetworkGatewayListResultPage struct {
	fn    func(context.Context, LocalNetworkGatewayListResult) (LocalNetworkGatewayListResult, error)
	lnglr LocalNetworkGatewayListResult
}

// 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 *LocalNetworkGatewayListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/LocalNetworkGatewayListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.lnglr)
	if err != nil {
		return err
	}
	page.lnglr = next
	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 *LocalNetworkGatewayListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page LocalNetworkGatewayListResultPage) Response() LocalNetworkGatewayListResult {
	return page.lnglr
}

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

// LocalNetworkGatewayPropertiesFormat localNetworkGateway properties
type LocalNetworkGatewayPropertiesFormat struct {
	// LocalNetworkAddressSpace - Local network site address space.
	LocalNetworkAddressSpace *AddressSpace `json:"localNetworkAddressSpace,omitempty"`
	// GatewayIPAddress - IP address of local network gateway.
	GatewayIPAddress *string `json:"gatewayIpAddress,omitempty"`
	// BgpSettings - Local network gateway's BGP speaker settings.
	BgpSettings *BgpSettings `json:"bgpSettings,omitempty"`
	// ResourceGUID - The resource GUID property of the LocalNetworkGateway resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the LocalNetworkGateway resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// LocalNetworkGatewaysCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type LocalNetworkGatewaysCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LocalNetworkGatewaysCreateOrUpdateFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if lng.Response.Response, err = future.GetResult(sender); err == nil && lng.Response.Response.StatusCode != http.StatusNoContent {
		lng, err = client.CreateOrUpdateResponder(lng.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysCreateOrUpdateFuture", "Result", lng.Response.Response, "Failure responding to request")
		}
	}
	return
}

// LocalNetworkGatewaysDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type LocalNetworkGatewaysDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LocalNetworkGatewaysDeleteFuture) Result(client LocalNetworkGatewaysClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// LocalNetworkGatewaysUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type LocalNetworkGatewaysUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *LocalNetworkGatewaysUpdateTagsFuture) Result(client LocalNetworkGatewaysClient) (lng LocalNetworkGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.LocalNetworkGatewaysUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if lng.Response.Response, err = future.GetResult(sender); err == nil && lng.Response.Response.StatusCode != http.StatusNoContent {
		lng, err = client.UpdateTagsResponder(lng.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.LocalNetworkGatewaysUpdateTagsFuture", "Result", lng.Response.Response, "Failure responding to request")
		}
	}
	return
}

// LogSpecification description of logging specification.
type LogSpecification struct {
	// Name - The name of the specification.
	Name *string `json:"name,omitempty"`
	// DisplayName - The display name of the specification.
	DisplayName *string `json:"displayName,omitempty"`
	// BlobDuration - Duration of the blob.
	BlobDuration *string `json:"blobDuration,omitempty"`
}

// MetricSpecification description of metrics specification.
type MetricSpecification struct {
	// Name - The name of the metric.
	Name *string `json:"name,omitempty"`
	// DisplayName - The display name of the metric.
	DisplayName *string `json:"displayName,omitempty"`
	// DisplayDescription - The description of the metric.
	DisplayDescription *string `json:"displayDescription,omitempty"`
	// Unit - Units the metric to be displayed in.
	Unit *string `json:"unit,omitempty"`
	// AggregationType - The aggregation type.
	AggregationType *string `json:"aggregationType,omitempty"`
	// Availabilities - List of availability.
	Availabilities *[]Availability `json:"availabilities,omitempty"`
	// EnableRegionalMdmAccount - Whether regional MDM account enabled.
	EnableRegionalMdmAccount *bool `json:"enableRegionalMdmAccount,omitempty"`
	// FillGapWithZero - Whether gaps would be filled with zeros.
	FillGapWithZero *bool `json:"fillGapWithZero,omitempty"`
	// MetricFilterPattern - Pattern for the filter of the metric.
	MetricFilterPattern *string `json:"metricFilterPattern,omitempty"`
	// Dimensions - List of dimensions.
	Dimensions *[]Dimension `json:"dimensions,omitempty"`
	// IsInternal - Whether the metric is internal.
	IsInternal *bool `json:"isInternal,omitempty"`
	// SourceMdmAccount - The source MDM account.
	SourceMdmAccount *string `json:"sourceMdmAccount,omitempty"`
	// SourceMdmNamespace - The source MDM namespace.
	SourceMdmNamespace *string `json:"sourceMdmNamespace,omitempty"`
	// ResourceIDDimensionNameOverride - The resource Id dimension name override.
	ResourceIDDimensionNameOverride *string `json:"resourceIdDimensionNameOverride,omitempty"`
}

// NextHopParameters parameters that define the source and destination endpoint.
type NextHopParameters struct {
	// TargetResourceID - The resource identifier of the target resource against which the action is to be performed.
	TargetResourceID *string `json:"targetResourceId,omitempty"`
	// SourceIPAddress - The source IP address.
	SourceIPAddress *string `json:"sourceIPAddress,omitempty"`
	// DestinationIPAddress - The destination IP address.
	DestinationIPAddress *string `json:"destinationIPAddress,omitempty"`
	// TargetNicResourceID - The NIC ID. (If VM has multiple NICs and IP forwarding is enabled on any of the nics, then this parameter must be specified. Otherwise optional).
	TargetNicResourceID *string `json:"targetNicResourceId,omitempty"`
}

// NextHopResult the information about next hop from the specified VM.
type NextHopResult struct {
	autorest.Response `json:"-"`
	// NextHopType - Next hop type. Possible values include: 'NextHopTypeInternet', 'NextHopTypeVirtualAppliance', 'NextHopTypeVirtualNetworkGateway', 'NextHopTypeVnetLocal', 'NextHopTypeHyperNetGateway', 'NextHopTypeNone'
	NextHopType NextHopType `json:"nextHopType,omitempty"`
	// NextHopIPAddress - Next hop IP Address
	NextHopIPAddress *string `json:"nextHopIpAddress,omitempty"`
	// RouteTableID - The resource identifier for the route table associated with the route being returned. If the route being returned does not correspond to any user created routes then this field will be the string 'System Route'.
	RouteTableID *string `json:"routeTableId,omitempty"`
}

// Operation network REST API operation definition.
type Operation struct {
	// Name - Operation name: {provider}/{resource}/{operation}
	Name *string `json:"name,omitempty"`
	// Display - Display metadata associated with the operation.
	Display *OperationDisplay `json:"display,omitempty"`
	// Origin - Origin of the operation.
	Origin *string `json:"origin,omitempty"`
	// OperationPropertiesFormat - Operation properties format.
	*OperationPropertiesFormat `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for Operation struct.
func (o *Operation) 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 "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				o.Name = &name
			}
		case "display":
			if v != nil {
				var display OperationDisplay
				err = json.Unmarshal(*v, &display)
				if err != nil {
					return err
				}
				o.Display = &display
			}
		case "origin":
			if v != nil {
				var origin string
				err = json.Unmarshal(*v, &origin)
				if err != nil {
					return err
				}
				o.Origin = &origin
			}
		case "properties":
			if v != nil {
				var operationPropertiesFormat OperationPropertiesFormat
				err = json.Unmarshal(*v, &operationPropertiesFormat)
				if err != nil {
					return err
				}
				o.OperationPropertiesFormat = &operationPropertiesFormat
			}
		}
	}

	return nil
}

// OperationDisplay display metadata associated with the operation.
type OperationDisplay struct {
	// Provider - Service provider: Microsoft Network.
	Provider *string `json:"provider,omitempty"`
	// Resource - Resource on which the operation is performed.
	Resource *string `json:"resource,omitempty"`
	// Operation - Type of the operation: get, read, delete, etc.
	Operation *string `json:"operation,omitempty"`
	// Description - Description of the operation.
	Description *string `json:"description,omitempty"`
}

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

// OperationListResultIterator provides access to a complete listing of Operation values.
type OperationListResultIterator struct {
	i    int
	page OperationListResultPage
}

// 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 *OperationListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/OperationListResultIterator.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 *OperationListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter OperationListResultIterator) 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 OperationListResultIterator) Response() OperationListResult {
	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 OperationListResultIterator) Value() Operation {
	if !iter.page.NotDone() {
		return Operation{}
	}
	return iter.page.Values()[iter.i]
}

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

// operationListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (olr OperationListResult) operationListResultPreparer(ctx context.Context) (*http.Request, error) {
	if olr.NextLink == nil || len(to.String(olr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(olr.NextLink)))
}

// OperationListResultPage contains a page of Operation values.
type OperationListResultPage struct {
	fn  func(context.Context, OperationListResult) (OperationListResult, error)
	olr OperationListResult
}

// 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 *OperationListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/OperationListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.olr)
	if err != nil {
		return err
	}
	page.olr = next
	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 *OperationListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page OperationListResultPage) Response() OperationListResult {
	return page.olr
}

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

// OperationPropertiesFormat description of operation properties format.
type OperationPropertiesFormat struct {
	// ServiceSpecification - Specification of the service.
	ServiceSpecification *OperationPropertiesFormatServiceSpecification `json:"serviceSpecification,omitempty"`
}

// OperationPropertiesFormatServiceSpecification specification of the service.
type OperationPropertiesFormatServiceSpecification struct {
	// MetricSpecifications - Operation service specification.
	MetricSpecifications *[]MetricSpecification `json:"metricSpecifications,omitempty"`
	// LogSpecifications - Operation log specification.
	LogSpecifications *[]LogSpecification `json:"logSpecifications,omitempty"`
}

// OutboundNatRule outbound NAT pool of the load balancer.
type OutboundNatRule struct {
	// OutboundNatRulePropertiesFormat - Properties of load balancer outbound nat rule.
	*OutboundNatRulePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for OutboundNatRule.
func (onr OutboundNatRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if onr.OutboundNatRulePropertiesFormat != nil {
		objectMap["properties"] = onr.OutboundNatRulePropertiesFormat
	}
	if onr.Name != nil {
		objectMap["name"] = onr.Name
	}
	if onr.Etag != nil {
		objectMap["etag"] = onr.Etag
	}
	if onr.ID != nil {
		objectMap["id"] = onr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for OutboundNatRule struct.
func (onr *OutboundNatRule) 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 {
				var outboundNatRulePropertiesFormat OutboundNatRulePropertiesFormat
				err = json.Unmarshal(*v, &outboundNatRulePropertiesFormat)
				if err != nil {
					return err
				}
				onr.OutboundNatRulePropertiesFormat = &outboundNatRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				onr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				onr.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				onr.ID = &ID
			}
		}
	}

	return nil
}

// OutboundNatRulePropertiesFormat outbound NAT pool of the load balancer.
type OutboundNatRulePropertiesFormat struct {
	// AllocatedOutboundPorts - The number of outbound ports to be used for NAT.
	AllocatedOutboundPorts *int32 `json:"allocatedOutboundPorts,omitempty"`
	// FrontendIPConfigurations - The Frontend IP addresses of the load balancer.
	FrontendIPConfigurations *[]SubResource `json:"frontendIPConfigurations,omitempty"`
	// BackendAddressPool - A reference to a pool of DIPs. Outbound traffic is randomly load balanced across IPs in the backend IPs.
	BackendAddressPool *SubResource `json:"backendAddressPool,omitempty"`
	// ProvisioningState - Gets the provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// PacketCapture parameters that define the create packet capture operation.
type PacketCapture struct {
	*PacketCaptureParameters `json:"properties,omitempty"`
}

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

// UnmarshalJSON is the custom unmarshaler for PacketCapture struct.
func (pc *PacketCapture) 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 {
				var packetCaptureParameters PacketCaptureParameters
				err = json.Unmarshal(*v, &packetCaptureParameters)
				if err != nil {
					return err
				}
				pc.PacketCaptureParameters = &packetCaptureParameters
			}
		}
	}

	return nil
}

// PacketCaptureFilter filter that is applied to packet capture request. Multiple filters can be applied.
type PacketCaptureFilter struct {
	// Protocol - Protocol to be filtered on. Possible values include: 'PcProtocolTCP', 'PcProtocolUDP', 'PcProtocolAny'
	Protocol PcProtocol `json:"protocol,omitempty"`
	// LocalIPAddress - Local IP Address to be filtered on. Notation: "127.0.0.1" for single address entry. "127.0.0.1-127.0.0.255" for range. "127.0.0.1;127.0.0.5"? for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Default = null.
	LocalIPAddress *string `json:"localIPAddress,omitempty"`
	// RemoteIPAddress - Local IP Address to be filtered on. Notation: "127.0.0.1" for single address entry. "127.0.0.1-127.0.0.255" for range. "127.0.0.1;127.0.0.5;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Default = null.
	RemoteIPAddress *string `json:"remoteIPAddress,omitempty"`
	// LocalPort - Local port to be filtered on. Notation: "80" for single port entry."80-85" for range. "80;443;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Default = null.
	LocalPort *string `json:"localPort,omitempty"`
	// RemotePort - Remote port to be filtered on. Notation: "80" for single port entry."80-85" for range. "80;443;" for multiple entries. Multiple ranges not currently supported. Mixing ranges with multiple entries not currently supported. Default = null.
	RemotePort *string `json:"remotePort,omitempty"`
}

// PacketCaptureListResult list of packet capture sessions.
type PacketCaptureListResult struct {
	autorest.Response `json:"-"`
	// Value - Information about packet capture sessions.
	Value *[]PacketCaptureResult `json:"value,omitempty"`
}

// PacketCaptureParameters parameters that define the create packet capture operation.
type PacketCaptureParameters struct {
	// Target - The ID of the targeted resource, only VM is currently supported.
	Target *string `json:"target,omitempty"`
	// BytesToCapturePerPacket - Number of bytes captured per packet, the remaining bytes are truncated.
	BytesToCapturePerPacket *int32 `json:"bytesToCapturePerPacket,omitempty"`
	// TotalBytesPerSession - Maximum size of the capture output.
	TotalBytesPerSession *int32 `json:"totalBytesPerSession,omitempty"`
	// TimeLimitInSeconds - Maximum duration of the capture session in seconds.
	TimeLimitInSeconds *int32                        `json:"timeLimitInSeconds,omitempty"`
	StorageLocation    *PacketCaptureStorageLocation `json:"storageLocation,omitempty"`
	Filters            *[]PacketCaptureFilter        `json:"filters,omitempty"`
}

// PacketCaptureQueryStatusResult status of packet capture session.
type PacketCaptureQueryStatusResult struct {
	autorest.Response `json:"-"`
	// Name - The name of the packet capture resource.
	Name *string `json:"name,omitempty"`
	// ID - The ID of the packet capture resource.
	ID *string `json:"id,omitempty"`
	// CaptureStartTime - The start time of the packet capture session.
	CaptureStartTime *date.Time `json:"captureStartTime,omitempty"`
	// PacketCaptureStatus - The status of the packet capture session. Possible values include: 'PcStatusNotStarted', 'PcStatusRunning', 'PcStatusStopped', 'PcStatusError', 'PcStatusUnknown'
	PacketCaptureStatus PcStatus `json:"packetCaptureStatus,omitempty"`
	// StopReason - The reason the current packet capture session was stopped.
	StopReason *string `json:"stopReason,omitempty"`
	// PacketCaptureError - List of errors of packet capture session.
	PacketCaptureError *[]PcError `json:"packetCaptureError,omitempty"`
}

// PacketCaptureResult information about packet capture session.
type PacketCaptureResult struct {
	autorest.Response `json:"-"`
	// Name - Name of the packet capture session.
	Name *string `json:"name,omitempty"`
	// ID - ID of the packet capture operation.
	ID                             *string `json:"id,omitempty"`
	Etag                           *string `json:"etag,omitempty"`
	*PacketCaptureResultProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for PacketCaptureResult.
func (pcr PacketCaptureResult) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if pcr.Name != nil {
		objectMap["name"] = pcr.Name
	}
	if pcr.ID != nil {
		objectMap["id"] = pcr.ID
	}
	if pcr.Etag != nil {
		objectMap["etag"] = pcr.Etag
	}
	if pcr.PacketCaptureResultProperties != nil {
		objectMap["properties"] = pcr.PacketCaptureResultProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for PacketCaptureResult struct.
func (pcr *PacketCaptureResult) 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 "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				pcr.Name = &name
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				pcr.ID = &ID
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				pcr.Etag = &etag
			}
		case "properties":
			if v != nil {
				var packetCaptureResultProperties PacketCaptureResultProperties
				err = json.Unmarshal(*v, &packetCaptureResultProperties)
				if err != nil {
					return err
				}
				pcr.PacketCaptureResultProperties = &packetCaptureResultProperties
			}
		}
	}

	return nil
}

// PacketCaptureResultProperties describes the properties of a packet capture session.
type PacketCaptureResultProperties struct {
	// ProvisioningState - The provisioning state of the packet capture session. Possible values include: 'ProvisioningStateSucceeded', 'ProvisioningStateUpdating', 'ProvisioningStateDeleting', 'ProvisioningStateFailed'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
	// Target - The ID of the targeted resource, only VM is currently supported.
	Target *string `json:"target,omitempty"`
	// BytesToCapturePerPacket - Number of bytes captured per packet, the remaining bytes are truncated.
	BytesToCapturePerPacket *int32 `json:"bytesToCapturePerPacket,omitempty"`
	// TotalBytesPerSession - Maximum size of the capture output.
	TotalBytesPerSession *int32 `json:"totalBytesPerSession,omitempty"`
	// TimeLimitInSeconds - Maximum duration of the capture session in seconds.
	TimeLimitInSeconds *int32                        `json:"timeLimitInSeconds,omitempty"`
	StorageLocation    *PacketCaptureStorageLocation `json:"storageLocation,omitempty"`
	Filters            *[]PacketCaptureFilter        `json:"filters,omitempty"`
}

// PacketCapturesCreateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PacketCapturesCreateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PacketCapturesCreateFuture) Result(client PacketCapturesClient) (pcr PacketCaptureResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PacketCapturesCreateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if pcr.Response.Response, err = future.GetResult(sender); err == nil && pcr.Response.Response.StatusCode != http.StatusNoContent {
		pcr, err = client.CreateResponder(pcr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.PacketCapturesCreateFuture", "Result", pcr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// PacketCapturesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PacketCapturesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PacketCapturesDeleteFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PacketCapturesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PacketCapturesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// PacketCapturesGetStatusFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PacketCapturesGetStatusFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PacketCapturesGetStatusFuture) Result(client PacketCapturesClient) (pcqsr PacketCaptureQueryStatusResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PacketCapturesGetStatusFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if pcqsr.Response.Response, err = future.GetResult(sender); err == nil && pcqsr.Response.Response.StatusCode != http.StatusNoContent {
		pcqsr, err = client.GetStatusResponder(pcqsr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.PacketCapturesGetStatusFuture", "Result", pcqsr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// PacketCapturesStopFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PacketCapturesStopFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PacketCapturesStopFuture) Result(client PacketCapturesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PacketCapturesStopFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PacketCapturesStopFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// PacketCaptureStorageLocation describes the storage location for a packet capture session.
type PacketCaptureStorageLocation struct {
	// StorageID - The ID of the storage account to save the packet capture session. Required if no local file path is provided.
	StorageID *string `json:"storageId,omitempty"`
	// StoragePath - The URI of the storage path to save the packet capture. Must be a well-formed URI describing the location to save the packet capture.
	StoragePath *string `json:"storagePath,omitempty"`
	// FilePath - A valid local path on the targeting VM. Must include the name of the capture file (*.cap). For linux virtual machine it must start with /var/captures. Required if no storage ID is provided, otherwise optional.
	FilePath *string `json:"filePath,omitempty"`
}

// PatchRouteFilter route Filter Resource.
type PatchRouteFilter struct {
	*RouteFilterPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for PatchRouteFilter.
func (prf PatchRouteFilter) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if prf.RouteFilterPropertiesFormat != nil {
		objectMap["properties"] = prf.RouteFilterPropertiesFormat
	}
	if prf.Name != nil {
		objectMap["name"] = prf.Name
	}
	if prf.Etag != nil {
		objectMap["etag"] = prf.Etag
	}
	if prf.Type != nil {
		objectMap["type"] = prf.Type
	}
	if prf.Tags != nil {
		objectMap["tags"] = prf.Tags
	}
	if prf.ID != nil {
		objectMap["id"] = prf.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for PatchRouteFilter struct.
func (prf *PatchRouteFilter) 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 {
				var routeFilterPropertiesFormat RouteFilterPropertiesFormat
				err = json.Unmarshal(*v, &routeFilterPropertiesFormat)
				if err != nil {
					return err
				}
				prf.RouteFilterPropertiesFormat = &routeFilterPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				prf.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				prf.Etag = &etag
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				prf.Type = &typeVar
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				prf.Tags = tags
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				prf.ID = &ID
			}
		}
	}

	return nil
}

// PatchRouteFilterRule route Filter Rule Resource
type PatchRouteFilterRule struct {
	*RouteFilterRulePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for PatchRouteFilterRule.
func (prfr PatchRouteFilterRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if prfr.RouteFilterRulePropertiesFormat != nil {
		objectMap["properties"] = prfr.RouteFilterRulePropertiesFormat
	}
	if prfr.Name != nil {
		objectMap["name"] = prfr.Name
	}
	if prfr.Etag != nil {
		objectMap["etag"] = prfr.Etag
	}
	if prfr.Tags != nil {
		objectMap["tags"] = prfr.Tags
	}
	if prfr.ID != nil {
		objectMap["id"] = prfr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for PatchRouteFilterRule struct.
func (prfr *PatchRouteFilterRule) 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 {
				var routeFilterRulePropertiesFormat RouteFilterRulePropertiesFormat
				err = json.Unmarshal(*v, &routeFilterRulePropertiesFormat)
				if err != nil {
					return err
				}
				prfr.RouteFilterRulePropertiesFormat = &routeFilterRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				prfr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				prfr.Etag = &etag
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				prfr.Tags = tags
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				prfr.ID = &ID
			}
		}
	}

	return nil
}

// Probe a load balancer probe.
type Probe struct {
	autorest.Response `json:"-"`
	// ProbePropertiesFormat - Properties of load balancer probe.
	*ProbePropertiesFormat `json:"properties,omitempty"`
	// Name - Gets name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for Probe.
func (p Probe) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if p.ProbePropertiesFormat != nil {
		objectMap["properties"] = p.ProbePropertiesFormat
	}
	if p.Name != nil {
		objectMap["name"] = p.Name
	}
	if p.Etag != nil {
		objectMap["etag"] = p.Etag
	}
	if p.ID != nil {
		objectMap["id"] = p.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Probe struct.
func (p *Probe) 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 {
				var probePropertiesFormat ProbePropertiesFormat
				err = json.Unmarshal(*v, &probePropertiesFormat)
				if err != nil {
					return err
				}
				p.ProbePropertiesFormat = &probePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				p.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				p.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				p.ID = &ID
			}
		}
	}

	return nil
}

// ProbePropertiesFormat load balancer probe resource.
type ProbePropertiesFormat struct {
	// LoadBalancingRules - The load balancer rules that use this probe.
	LoadBalancingRules *[]SubResource `json:"loadBalancingRules,omitempty"`
	// Protocol - The protocol of the end point. Possible values are: 'Http' or 'Tcp'. If 'Tcp' is specified, a received ACK is required for the probe to be successful. If 'Http' is specified, a 200 OK response from the specifies URI is required for the probe to be successful. Possible values include: 'ProbeProtocolHTTP', 'ProbeProtocolTCP'
	Protocol ProbeProtocol `json:"protocol,omitempty"`
	// Port - The port for communicating the probe. Possible values range from 1 to 65535, inclusive.
	Port *int32 `json:"port,omitempty"`
	// IntervalInSeconds - The interval, in seconds, for how frequently to probe the endpoint for health status. Typically, the interval is slightly less than half the allocated timeout period (in seconds) which allows two full probes before taking the instance out of rotation. The default value is 15, the minimum value is 5.
	IntervalInSeconds *int32 `json:"intervalInSeconds,omitempty"`
	// NumberOfProbes - The number of probes where if no response, will result in stopping further traffic from being delivered to the endpoint. This values allows endpoints to be taken out of rotation faster or slower than the typical times used in Azure.
	NumberOfProbes *int32 `json:"numberOfProbes,omitempty"`
	// RequestPath - The URI used for requesting health status from the VM. Path is required if a protocol is set to http. Otherwise, it is not allowed. There is no default value.
	RequestPath *string `json:"requestPath,omitempty"`
	// ProvisioningState - Gets the provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// PublicIPAddress public IP address resource.
type PublicIPAddress struct {
	autorest.Response `json:"-"`
	// Sku - The public IP address SKU.
	Sku *PublicIPAddressSku `json:"sku,omitempty"`
	// PublicIPAddressPropertiesFormat - Public IP address properties.
	*PublicIPAddressPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Zones - A list of availability zones denoting the IP allocated for the resource needs to come from.
	Zones *[]string `json:"zones,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for PublicIPAddress.
func (pia PublicIPAddress) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if pia.Sku != nil {
		objectMap["sku"] = pia.Sku
	}
	if pia.PublicIPAddressPropertiesFormat != nil {
		objectMap["properties"] = pia.PublicIPAddressPropertiesFormat
	}
	if pia.Etag != nil {
		objectMap["etag"] = pia.Etag
	}
	if pia.Zones != nil {
		objectMap["zones"] = pia.Zones
	}
	if pia.ID != nil {
		objectMap["id"] = pia.ID
	}
	if pia.Name != nil {
		objectMap["name"] = pia.Name
	}
	if pia.Type != nil {
		objectMap["type"] = pia.Type
	}
	if pia.Location != nil {
		objectMap["location"] = pia.Location
	}
	if pia.Tags != nil {
		objectMap["tags"] = pia.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for PublicIPAddress struct.
func (pia *PublicIPAddress) 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 "sku":
			if v != nil {
				var sku PublicIPAddressSku
				err = json.Unmarshal(*v, &sku)
				if err != nil {
					return err
				}
				pia.Sku = &sku
			}
		case "properties":
			if v != nil {
				var publicIPAddressPropertiesFormat PublicIPAddressPropertiesFormat
				err = json.Unmarshal(*v, &publicIPAddressPropertiesFormat)
				if err != nil {
					return err
				}
				pia.PublicIPAddressPropertiesFormat = &publicIPAddressPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				pia.Etag = &etag
			}
		case "zones":
			if v != nil {
				var zones []string
				err = json.Unmarshal(*v, &zones)
				if err != nil {
					return err
				}
				pia.Zones = &zones
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				pia.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				pia.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				pia.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				pia.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				pia.Tags = tags
			}
		}
	}

	return nil
}

// PublicIPAddressDNSSettings contains FQDN of the DNS record associated with the public IP address
type PublicIPAddressDNSSettings struct {
	// DomainNameLabel - Gets or sets the Domain name label.The concatenation of the domain name label and the regionalized DNS zone make up the fully qualified domain name associated with the public IP address. If a domain name label is specified, an A DNS record is created for the public IP in the Microsoft Azure DNS system.
	DomainNameLabel *string `json:"domainNameLabel,omitempty"`
	// Fqdn - Gets the FQDN, Fully qualified domain name of the A DNS record associated with the public IP. This is the concatenation of the domainNameLabel and the regionalized DNS zone.
	Fqdn *string `json:"fqdn,omitempty"`
	// ReverseFqdn - Gets or Sets the Reverse FQDN. A user-visible, fully qualified domain name that resolves to this public IP address. If the reverseFqdn is specified, then a PTR DNS record is created pointing from the IP address in the in-addr.arpa domain to the reverse FQDN.
	ReverseFqdn *string `json:"reverseFqdn,omitempty"`
}

// PublicIPAddressesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type PublicIPAddressesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PublicIPAddressesCreateOrUpdateFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if pia.Response.Response, err = future.GetResult(sender); err == nil && pia.Response.Response.StatusCode != http.StatusNoContent {
		pia, err = client.CreateOrUpdateResponder(pia.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.PublicIPAddressesCreateOrUpdateFuture", "Result", pia.Response.Response, "Failure responding to request")
		}
	}
	return
}

// PublicIPAddressesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type PublicIPAddressesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PublicIPAddressesDeleteFuture) Result(client PublicIPAddressesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PublicIPAddressesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// PublicIPAddressesUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type PublicIPAddressesUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *PublicIPAddressesUpdateTagsFuture) Result(client PublicIPAddressesClient) (pia PublicIPAddress, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.PublicIPAddressesUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if pia.Response.Response, err = future.GetResult(sender); err == nil && pia.Response.Response.StatusCode != http.StatusNoContent {
		pia, err = client.UpdateTagsResponder(pia.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.PublicIPAddressesUpdateTagsFuture", "Result", pia.Response.Response, "Failure responding to request")
		}
	}
	return
}

// PublicIPAddressListResult response for ListPublicIpAddresses API service call.
type PublicIPAddressListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of public IP addresses that exists in a resource group.
	Value *[]PublicIPAddress `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// PublicIPAddressListResultIterator provides access to a complete listing of PublicIPAddress values.
type PublicIPAddressListResultIterator struct {
	i    int
	page PublicIPAddressListResultPage
}

// 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 *PublicIPAddressListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/PublicIPAddressListResultIterator.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 *PublicIPAddressListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter PublicIPAddressListResultIterator) 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 PublicIPAddressListResultIterator) Response() PublicIPAddressListResult {
	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 PublicIPAddressListResultIterator) Value() PublicIPAddress {
	if !iter.page.NotDone() {
		return PublicIPAddress{}
	}
	return iter.page.Values()[iter.i]
}

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

// publicIPAddressListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (pialr PublicIPAddressListResult) publicIPAddressListResultPreparer(ctx context.Context) (*http.Request, error) {
	if pialr.NextLink == nil || len(to.String(pialr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(pialr.NextLink)))
}

// PublicIPAddressListResultPage contains a page of PublicIPAddress values.
type PublicIPAddressListResultPage struct {
	fn    func(context.Context, PublicIPAddressListResult) (PublicIPAddressListResult, error)
	pialr PublicIPAddressListResult
}

// 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 *PublicIPAddressListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/PublicIPAddressListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.pialr)
	if err != nil {
		return err
	}
	page.pialr = next
	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 *PublicIPAddressListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page PublicIPAddressListResultPage) Response() PublicIPAddressListResult {
	return page.pialr
}

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

// PublicIPAddressPropertiesFormat public IP address properties.
type PublicIPAddressPropertiesFormat struct {
	// PublicIPAllocationMethod - The public IP allocation method. Possible values are: 'Static' and 'Dynamic'. Possible values include: 'Static', 'Dynamic'
	PublicIPAllocationMethod IPAllocationMethod `json:"publicIPAllocationMethod,omitempty"`
	// PublicIPAddressVersion - The public IP address version. Possible values are: 'IPv4' and 'IPv6'. Possible values include: 'IPv4', 'IPv6'
	PublicIPAddressVersion IPVersion `json:"publicIPAddressVersion,omitempty"`
	// IPConfiguration - The IP configuration associated with the public IP address.
	IPConfiguration *IPConfiguration `json:"ipConfiguration,omitempty"`
	// DNSSettings - The FQDN of the DNS record associated with the public IP address.
	DNSSettings *PublicIPAddressDNSSettings `json:"dnsSettings,omitempty"`
	// IPAddress - The IP address associated with the public IP address resource.
	IPAddress *string `json:"ipAddress,omitempty"`
	// IdleTimeoutInMinutes - The idle timeout of the public IP address.
	IdleTimeoutInMinutes *int32 `json:"idleTimeoutInMinutes,omitempty"`
	// ResourceGUID - The resource GUID property of the public IP resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// PublicIPAddressSku SKU of a public IP address
type PublicIPAddressSku struct {
	// Name - Name of a public IP address SKU. Possible values include: 'PublicIPAddressSkuNameBasic', 'PublicIPAddressSkuNameStandard'
	Name PublicIPAddressSkuName `json:"name,omitempty"`
}

// QueryTroubleshootingParameters parameters that define the resource to query the troubleshooting result.
type QueryTroubleshootingParameters struct {
	// TargetResourceID - The target resource ID to query the troubleshooting result.
	TargetResourceID *string `json:"targetResourceId,omitempty"`
}

// Resource common resource representation.
type Resource struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Resource.
func (r Resource) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if r.ID != nil {
		objectMap["id"] = r.ID
	}
	if r.Name != nil {
		objectMap["name"] = r.Name
	}
	if r.Type != nil {
		objectMap["type"] = r.Type
	}
	if r.Location != nil {
		objectMap["location"] = r.Location
	}
	if r.Tags != nil {
		objectMap["tags"] = r.Tags
	}
	return json.Marshal(objectMap)
}

// ResourceNavigationLink resourceNavigationLink resource.
type ResourceNavigationLink struct {
	// ResourceNavigationLinkFormat - Resource navigation link properties format.
	*ResourceNavigationLinkFormat `json:"properties,omitempty"`
	// Name - Name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for ResourceNavigationLink.
func (rnl ResourceNavigationLink) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rnl.ResourceNavigationLinkFormat != nil {
		objectMap["properties"] = rnl.ResourceNavigationLinkFormat
	}
	if rnl.Name != nil {
		objectMap["name"] = rnl.Name
	}
	if rnl.Etag != nil {
		objectMap["etag"] = rnl.Etag
	}
	if rnl.ID != nil {
		objectMap["id"] = rnl.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for ResourceNavigationLink struct.
func (rnl *ResourceNavigationLink) 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 {
				var resourceNavigationLinkFormat ResourceNavigationLinkFormat
				err = json.Unmarshal(*v, &resourceNavigationLinkFormat)
				if err != nil {
					return err
				}
				rnl.ResourceNavigationLinkFormat = &resourceNavigationLinkFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				rnl.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				rnl.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				rnl.ID = &ID
			}
		}
	}

	return nil
}

// ResourceNavigationLinkFormat properties of ResourceNavigationLink.
type ResourceNavigationLinkFormat struct {
	// LinkedResourceType - Resource type of the linked resource.
	LinkedResourceType *string `json:"linkedResourceType,omitempty"`
	// Link - Link to the external resource
	Link *string `json:"link,omitempty"`
	// ProvisioningState - Provisioning state of the ResourceNavigationLink resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// RetentionPolicyParameters parameters that define the retention policy for flow log.
type RetentionPolicyParameters struct {
	// Days - Number of days to retain flow log records.
	Days *int32 `json:"days,omitempty"`
	// Enabled - Flag to enable/disable retention.
	Enabled *bool `json:"enabled,omitempty"`
}

// Route route resource
type Route struct {
	autorest.Response `json:"-"`
	// RoutePropertiesFormat - Properties of the route.
	*RoutePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for Route.
func (r Route) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if r.RoutePropertiesFormat != nil {
		objectMap["properties"] = r.RoutePropertiesFormat
	}
	if r.Name != nil {
		objectMap["name"] = r.Name
	}
	if r.Etag != nil {
		objectMap["etag"] = r.Etag
	}
	if r.ID != nil {
		objectMap["id"] = r.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Route struct.
func (r *Route) 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 {
				var routePropertiesFormat RoutePropertiesFormat
				err = json.Unmarshal(*v, &routePropertiesFormat)
				if err != nil {
					return err
				}
				r.RoutePropertiesFormat = &routePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				r.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				r.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				r.ID = &ID
			}
		}
	}

	return nil
}

// RouteFilter route Filter Resource.
type RouteFilter struct {
	autorest.Response            `json:"-"`
	*RouteFilterPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for RouteFilter.
func (rf RouteFilter) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rf.RouteFilterPropertiesFormat != nil {
		objectMap["properties"] = rf.RouteFilterPropertiesFormat
	}
	if rf.Etag != nil {
		objectMap["etag"] = rf.Etag
	}
	if rf.ID != nil {
		objectMap["id"] = rf.ID
	}
	if rf.Name != nil {
		objectMap["name"] = rf.Name
	}
	if rf.Type != nil {
		objectMap["type"] = rf.Type
	}
	if rf.Location != nil {
		objectMap["location"] = rf.Location
	}
	if rf.Tags != nil {
		objectMap["tags"] = rf.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for RouteFilter struct.
func (rf *RouteFilter) 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 {
				var routeFilterPropertiesFormat RouteFilterPropertiesFormat
				err = json.Unmarshal(*v, &routeFilterPropertiesFormat)
				if err != nil {
					return err
				}
				rf.RouteFilterPropertiesFormat = &routeFilterPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				rf.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				rf.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				rf.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				rf.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				rf.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				rf.Tags = tags
			}
		}
	}

	return nil
}

// RouteFilterListResult response for the ListRouteFilters API service call.
type RouteFilterListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of route filters in a resource group.
	Value *[]RouteFilter `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// RouteFilterListResultIterator provides access to a complete listing of RouteFilter values.
type RouteFilterListResultIterator struct {
	i    int
	page RouteFilterListResultPage
}

// 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 *RouteFilterListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteFilterListResultIterator.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 *RouteFilterListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter RouteFilterListResultIterator) 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 RouteFilterListResultIterator) Response() RouteFilterListResult {
	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 RouteFilterListResultIterator) Value() RouteFilter {
	if !iter.page.NotDone() {
		return RouteFilter{}
	}
	return iter.page.Values()[iter.i]
}

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

// routeFilterListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rflr RouteFilterListResult) routeFilterListResultPreparer(ctx context.Context) (*http.Request, error) {
	if rflr.NextLink == nil || len(to.String(rflr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rflr.NextLink)))
}

// RouteFilterListResultPage contains a page of RouteFilter values.
type RouteFilterListResultPage struct {
	fn   func(context.Context, RouteFilterListResult) (RouteFilterListResult, error)
	rflr RouteFilterListResult
}

// 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 *RouteFilterListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteFilterListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.rflr)
	if err != nil {
		return err
	}
	page.rflr = next
	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 *RouteFilterListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page RouteFilterListResultPage) Response() RouteFilterListResult {
	return page.rflr
}

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

// RouteFilterPropertiesFormat route Filter Resource
type RouteFilterPropertiesFormat struct {
	// Rules - Collection of RouteFilterRules contained within a route filter.
	Rules *[]RouteFilterRule `json:"rules,omitempty"`
	// Peerings - A collection of references to express route circuit peerings.
	Peerings *[]ExpressRouteCircuitPeering `json:"peerings,omitempty"`
	// ProvisioningState - The provisioning state of the resource. Possible values are: 'Updating', 'Deleting', 'Succeeded' and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// RouteFilterRule route Filter Rule Resource
type RouteFilterRule struct {
	autorest.Response                `json:"-"`
	*RouteFilterRulePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for RouteFilterRule.
func (rfr RouteFilterRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rfr.RouteFilterRulePropertiesFormat != nil {
		objectMap["properties"] = rfr.RouteFilterRulePropertiesFormat
	}
	if rfr.Name != nil {
		objectMap["name"] = rfr.Name
	}
	if rfr.Location != nil {
		objectMap["location"] = rfr.Location
	}
	if rfr.Etag != nil {
		objectMap["etag"] = rfr.Etag
	}
	if rfr.Tags != nil {
		objectMap["tags"] = rfr.Tags
	}
	if rfr.ID != nil {
		objectMap["id"] = rfr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for RouteFilterRule struct.
func (rfr *RouteFilterRule) 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 {
				var routeFilterRulePropertiesFormat RouteFilterRulePropertiesFormat
				err = json.Unmarshal(*v, &routeFilterRulePropertiesFormat)
				if err != nil {
					return err
				}
				rfr.RouteFilterRulePropertiesFormat = &routeFilterRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				rfr.Name = &name
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				rfr.Location = &location
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				rfr.Etag = &etag
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				rfr.Tags = tags
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				rfr.ID = &ID
			}
		}
	}

	return nil
}

// RouteFilterRuleListResult response for the ListRouteFilterRules API service call
type RouteFilterRuleListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of RouteFilterRules in a resource group.
	Value *[]RouteFilterRule `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// RouteFilterRuleListResultIterator provides access to a complete listing of RouteFilterRule values.
type RouteFilterRuleListResultIterator struct {
	i    int
	page RouteFilterRuleListResultPage
}

// 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 *RouteFilterRuleListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteFilterRuleListResultIterator.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 *RouteFilterRuleListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter RouteFilterRuleListResultIterator) 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 RouteFilterRuleListResultIterator) Response() RouteFilterRuleListResult {
	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 RouteFilterRuleListResultIterator) Value() RouteFilterRule {
	if !iter.page.NotDone() {
		return RouteFilterRule{}
	}
	return iter.page.Values()[iter.i]
}

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

// routeFilterRuleListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rfrlr RouteFilterRuleListResult) routeFilterRuleListResultPreparer(ctx context.Context) (*http.Request, error) {
	if rfrlr.NextLink == nil || len(to.String(rfrlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rfrlr.NextLink)))
}

// RouteFilterRuleListResultPage contains a page of RouteFilterRule values.
type RouteFilterRuleListResultPage struct {
	fn    func(context.Context, RouteFilterRuleListResult) (RouteFilterRuleListResult, error)
	rfrlr RouteFilterRuleListResult
}

// 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 *RouteFilterRuleListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteFilterRuleListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.rfrlr)
	if err != nil {
		return err
	}
	page.rfrlr = next
	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 *RouteFilterRuleListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page RouteFilterRuleListResultPage) Response() RouteFilterRuleListResult {
	return page.rfrlr
}

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

// RouteFilterRulePropertiesFormat route Filter Rule Resource
type RouteFilterRulePropertiesFormat struct {
	// Access - The access type of the rule. Valid values are: 'Allow', 'Deny'. Possible values include: 'Allow', 'Deny'
	Access Access `json:"access,omitempty"`
	// RouteFilterRuleType - The rule type of the rule. Valid value is: 'Community'
	RouteFilterRuleType *string `json:"routeFilterRuleType,omitempty"`
	// Communities - The collection for bgp community values to filter on. e.g. ['12076:5010','12076:5020']
	Communities *[]string `json:"communities,omitempty"`
	// ProvisioningState - The provisioning state of the resource. Possible values are: 'Updating', 'Deleting', 'Succeeded' and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// RouteFilterRulesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type RouteFilterRulesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFilterRulesCreateOrUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rfr.Response.Response, err = future.GetResult(sender); err == nil && rfr.Response.Response.StatusCode != http.StatusNoContent {
		rfr, err = client.CreateOrUpdateResponder(rfr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteFilterRulesCreateOrUpdateFuture", "Result", rfr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RouteFilterRulesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteFilterRulesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFilterRulesDeleteFuture) Result(client RouteFilterRulesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFilterRulesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// RouteFilterRulesUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteFilterRulesUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFilterRulesUpdateFuture) Result(client RouteFilterRulesClient) (rfr RouteFilterRule, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFilterRulesUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rfr.Response.Response, err = future.GetResult(sender); err == nil && rfr.Response.Response.StatusCode != http.StatusNoContent {
		rfr, err = client.UpdateResponder(rfr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteFilterRulesUpdateFuture", "Result", rfr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RouteFiltersCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type RouteFiltersCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFiltersCreateOrUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFiltersCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rf.Response.Response, err = future.GetResult(sender); err == nil && rf.Response.Response.StatusCode != http.StatusNoContent {
		rf, err = client.CreateOrUpdateResponder(rf.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteFiltersCreateOrUpdateFuture", "Result", rf.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RouteFiltersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteFiltersDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFiltersDeleteFuture) Result(client RouteFiltersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFiltersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFiltersDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// RouteFiltersUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteFiltersUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteFiltersUpdateFuture) Result(client RouteFiltersClient) (rf RouteFilter, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteFiltersUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rf.Response.Response, err = future.GetResult(sender); err == nil && rf.Response.Response.StatusCode != http.StatusNoContent {
		rf, err = client.UpdateResponder(rf.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteFiltersUpdateFuture", "Result", rf.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RouteListResult response for the ListRoute API service call
type RouteListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of routes in a resource group.
	Value *[]Route `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// RouteListResultIterator provides access to a complete listing of Route values.
type RouteListResultIterator struct {
	i    int
	page RouteListResultPage
}

// 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 *RouteListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteListResultIterator.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 *RouteListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter RouteListResultIterator) 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 RouteListResultIterator) Response() RouteListResult {
	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 RouteListResultIterator) Value() Route {
	if !iter.page.NotDone() {
		return Route{}
	}
	return iter.page.Values()[iter.i]
}

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

// routeListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rlr RouteListResult) routeListResultPreparer(ctx context.Context) (*http.Request, error) {
	if rlr.NextLink == nil || len(to.String(rlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rlr.NextLink)))
}

// RouteListResultPage contains a page of Route values.
type RouteListResultPage struct {
	fn  func(context.Context, RouteListResult) (RouteListResult, error)
	rlr RouteListResult
}

// 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 *RouteListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.rlr)
	if err != nil {
		return err
	}
	page.rlr = next
	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 *RouteListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page RouteListResultPage) Response() RouteListResult {
	return page.rlr
}

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

// RoutePropertiesFormat route resource
type RoutePropertiesFormat struct {
	// AddressPrefix - The destination CIDR to which the route applies.
	AddressPrefix *string `json:"addressPrefix,omitempty"`
	// NextHopType - The type of Azure hop the packet should be sent to. Possible values are: 'VirtualNetworkGateway', 'VnetLocal', 'Internet', 'VirtualAppliance', and 'None'. Possible values include: 'RouteNextHopTypeVirtualNetworkGateway', 'RouteNextHopTypeVnetLocal', 'RouteNextHopTypeInternet', 'RouteNextHopTypeVirtualAppliance', 'RouteNextHopTypeNone'
	NextHopType RouteNextHopType `json:"nextHopType,omitempty"`
	// NextHopIPAddress - The IP address packets should be forwarded to. Next hop values are only allowed in routes where the next hop type is VirtualAppliance.
	NextHopIPAddress *string `json:"nextHopIpAddress,omitempty"`
	// ProvisioningState - The provisioning state of the resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// RoutesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RoutesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RoutesCreateOrUpdateFuture) Result(client RoutesClient) (r Route, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RoutesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if r.Response.Response, err = future.GetResult(sender); err == nil && r.Response.Response.StatusCode != http.StatusNoContent {
		r, err = client.CreateOrUpdateResponder(r.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RoutesCreateOrUpdateFuture", "Result", r.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RoutesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running operation.
type RoutesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RoutesDeleteFuture) Result(client RoutesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RoutesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RoutesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// RouteTable route table resource.
type RouteTable struct {
	autorest.Response `json:"-"`
	// RouteTablePropertiesFormat - Properties of the route table.
	*RouteTablePropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for RouteTable.
func (rt RouteTable) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if rt.RouteTablePropertiesFormat != nil {
		objectMap["properties"] = rt.RouteTablePropertiesFormat
	}
	if rt.Etag != nil {
		objectMap["etag"] = rt.Etag
	}
	if rt.ID != nil {
		objectMap["id"] = rt.ID
	}
	if rt.Name != nil {
		objectMap["name"] = rt.Name
	}
	if rt.Type != nil {
		objectMap["type"] = rt.Type
	}
	if rt.Location != nil {
		objectMap["location"] = rt.Location
	}
	if rt.Tags != nil {
		objectMap["tags"] = rt.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for RouteTable struct.
func (rt *RouteTable) 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 {
				var routeTablePropertiesFormat RouteTablePropertiesFormat
				err = json.Unmarshal(*v, &routeTablePropertiesFormat)
				if err != nil {
					return err
				}
				rt.RouteTablePropertiesFormat = &routeTablePropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				rt.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				rt.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				rt.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				rt.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				rt.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				rt.Tags = tags
			}
		}
	}

	return nil
}

// RouteTableListResult response for the ListRouteTable API service call.
type RouteTableListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of route tables in a resource group.
	Value *[]RouteTable `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// RouteTableListResultIterator provides access to a complete listing of RouteTable values.
type RouteTableListResultIterator struct {
	i    int
	page RouteTableListResultPage
}

// 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 *RouteTableListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteTableListResultIterator.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 *RouteTableListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter RouteTableListResultIterator) 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 RouteTableListResultIterator) Response() RouteTableListResult {
	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 RouteTableListResultIterator) Value() RouteTable {
	if !iter.page.NotDone() {
		return RouteTable{}
	}
	return iter.page.Values()[iter.i]
}

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

// routeTableListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (rtlr RouteTableListResult) routeTableListResultPreparer(ctx context.Context) (*http.Request, error) {
	if rtlr.NextLink == nil || len(to.String(rtlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(rtlr.NextLink)))
}

// RouteTableListResultPage contains a page of RouteTable values.
type RouteTableListResultPage struct {
	fn   func(context.Context, RouteTableListResult) (RouteTableListResult, error)
	rtlr RouteTableListResult
}

// 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 *RouteTableListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/RouteTableListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.rtlr)
	if err != nil {
		return err
	}
	page.rtlr = next
	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 *RouteTableListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page RouteTableListResultPage) Response() RouteTableListResult {
	return page.rtlr
}

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

// RouteTablePropertiesFormat route Table resource
type RouteTablePropertiesFormat struct {
	// Routes - Collection of routes contained within a route table.
	Routes *[]Route `json:"routes,omitempty"`
	// Subnets - A collection of references to subnets.
	Subnets *[]Subnet `json:"subnets,omitempty"`
	// ProvisioningState - The provisioning state of the resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// RouteTablesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type RouteTablesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteTablesCreateOrUpdateFuture) Result(client RouteTablesClient) (rt RouteTable, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteTablesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rt.Response.Response, err = future.GetResult(sender); err == nil && rt.Response.Response.StatusCode != http.StatusNoContent {
		rt, err = client.CreateOrUpdateResponder(rt.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteTablesCreateOrUpdateFuture", "Result", rt.Response.Response, "Failure responding to request")
		}
	}
	return
}

// RouteTablesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteTablesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteTablesDeleteFuture) Result(client RouteTablesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteTablesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteTablesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// RouteTablesUpdateTagsFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type RouteTablesUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *RouteTablesUpdateTagsFuture) Result(client RouteTablesClient) (rt RouteTable, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.RouteTablesUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if rt.Response.Response, err = future.GetResult(sender); err == nil && rt.Response.Response.StatusCode != http.StatusNoContent {
		rt, err = client.UpdateTagsResponder(rt.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.RouteTablesUpdateTagsFuture", "Result", rt.Response.Response, "Failure responding to request")
		}
	}
	return
}

// SecurityGroup networkSecurityGroup resource.
type SecurityGroup struct {
	autorest.Response `json:"-"`
	// SecurityGroupPropertiesFormat - Properties of the network security group
	*SecurityGroupPropertiesFormat `json:"properties,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for SecurityGroup.
func (sg SecurityGroup) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if sg.SecurityGroupPropertiesFormat != nil {
		objectMap["properties"] = sg.SecurityGroupPropertiesFormat
	}
	if sg.Etag != nil {
		objectMap["etag"] = sg.Etag
	}
	if sg.ID != nil {
		objectMap["id"] = sg.ID
	}
	if sg.Name != nil {
		objectMap["name"] = sg.Name
	}
	if sg.Type != nil {
		objectMap["type"] = sg.Type
	}
	if sg.Location != nil {
		objectMap["location"] = sg.Location
	}
	if sg.Tags != nil {
		objectMap["tags"] = sg.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for SecurityGroup struct.
func (sg *SecurityGroup) 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 {
				var securityGroupPropertiesFormat SecurityGroupPropertiesFormat
				err = json.Unmarshal(*v, &securityGroupPropertiesFormat)
				if err != nil {
					return err
				}
				sg.SecurityGroupPropertiesFormat = &securityGroupPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				sg.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				sg.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				sg.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				sg.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				sg.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				sg.Tags = tags
			}
		}
	}

	return nil
}

// SecurityGroupListResult response for ListNetworkSecurityGroups API service call.
type SecurityGroupListResult struct {
	autorest.Response `json:"-"`
	// Value - A list of NetworkSecurityGroup resources.
	Value *[]SecurityGroup `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// SecurityGroupListResultIterator provides access to a complete listing of SecurityGroup values.
type SecurityGroupListResultIterator struct {
	i    int
	page SecurityGroupListResultPage
}

// 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 *SecurityGroupListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SecurityGroupListResultIterator.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 *SecurityGroupListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter SecurityGroupListResultIterator) 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 SecurityGroupListResultIterator) Response() SecurityGroupListResult {
	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 SecurityGroupListResultIterator) Value() SecurityGroup {
	if !iter.page.NotDone() {
		return SecurityGroup{}
	}
	return iter.page.Values()[iter.i]
}

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

// securityGroupListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (sglr SecurityGroupListResult) securityGroupListResultPreparer(ctx context.Context) (*http.Request, error) {
	if sglr.NextLink == nil || len(to.String(sglr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(sglr.NextLink)))
}

// SecurityGroupListResultPage contains a page of SecurityGroup values.
type SecurityGroupListResultPage struct {
	fn   func(context.Context, SecurityGroupListResult) (SecurityGroupListResult, error)
	sglr SecurityGroupListResult
}

// 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 *SecurityGroupListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SecurityGroupListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.sglr)
	if err != nil {
		return err
	}
	page.sglr = next
	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 *SecurityGroupListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page SecurityGroupListResultPage) Response() SecurityGroupListResult {
	return page.sglr
}

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

// SecurityGroupNetworkInterface network interface and all its associated security rules.
type SecurityGroupNetworkInterface struct {
	// ID - ID of the network interface.
	ID                       *string                   `json:"id,omitempty"`
	SecurityRuleAssociations *SecurityRuleAssociations `json:"securityRuleAssociations,omitempty"`
}

// SecurityGroupPropertiesFormat network Security Group resource.
type SecurityGroupPropertiesFormat struct {
	// SecurityRules - A collection of security rules of the network security group.
	SecurityRules *[]SecurityRule `json:"securityRules,omitempty"`
	// DefaultSecurityRules - The default security rules of network security group.
	DefaultSecurityRules *[]SecurityRule `json:"defaultSecurityRules,omitempty"`
	// NetworkInterfaces - A collection of references to network interfaces.
	NetworkInterfaces *[]Interface `json:"networkInterfaces,omitempty"`
	// Subnets - A collection of references to subnets.
	Subnets *[]Subnet `json:"subnets,omitempty"`
	// ResourceGUID - The resource GUID property of the network security group resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// SecurityGroupsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type SecurityGroupsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SecurityGroupsCreateOrUpdateFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if sg.Response.Response, err = future.GetResult(sender); err == nil && sg.Response.Response.StatusCode != http.StatusNoContent {
		sg, err = client.CreateOrUpdateResponder(sg.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.SecurityGroupsCreateOrUpdateFuture", "Result", sg.Response.Response, "Failure responding to request")
		}
	}
	return
}

// SecurityGroupsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type SecurityGroupsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SecurityGroupsDeleteFuture) Result(client SecurityGroupsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SecurityGroupsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// SecurityGroupsUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type SecurityGroupsUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SecurityGroupsUpdateTagsFuture) Result(client SecurityGroupsClient) (sg SecurityGroup, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SecurityGroupsUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if sg.Response.Response, err = future.GetResult(sender); err == nil && sg.Response.Response.StatusCode != http.StatusNoContent {
		sg, err = client.UpdateTagsResponder(sg.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.SecurityGroupsUpdateTagsFuture", "Result", sg.Response.Response, "Failure responding to request")
		}
	}
	return
}

// SecurityGroupViewParameters parameters that define the VM to check security groups for.
type SecurityGroupViewParameters struct {
	// TargetResourceID - ID of the target VM.
	TargetResourceID *string `json:"targetResourceId,omitempty"`
}

// SecurityGroupViewResult the information about security rules applied to the specified VM.
type SecurityGroupViewResult struct {
	autorest.Response `json:"-"`
	// NetworkInterfaces - List of network interfaces on the specified VM.
	NetworkInterfaces *[]SecurityGroupNetworkInterface `json:"networkInterfaces,omitempty"`
}

// SecurityRule network security rule.
type SecurityRule struct {
	autorest.Response `json:"-"`
	// SecurityRulePropertiesFormat - Properties of the security rule
	*SecurityRulePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for SecurityRule.
func (sr SecurityRule) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if sr.SecurityRulePropertiesFormat != nil {
		objectMap["properties"] = sr.SecurityRulePropertiesFormat
	}
	if sr.Name != nil {
		objectMap["name"] = sr.Name
	}
	if sr.Etag != nil {
		objectMap["etag"] = sr.Etag
	}
	if sr.ID != nil {
		objectMap["id"] = sr.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for SecurityRule struct.
func (sr *SecurityRule) 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 {
				var securityRulePropertiesFormat SecurityRulePropertiesFormat
				err = json.Unmarshal(*v, &securityRulePropertiesFormat)
				if err != nil {
					return err
				}
				sr.SecurityRulePropertiesFormat = &securityRulePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				sr.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				sr.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				sr.ID = &ID
			}
		}
	}

	return nil
}

// SecurityRuleAssociations all security rules associated with the network interface.
type SecurityRuleAssociations struct {
	NetworkInterfaceAssociation *InterfaceAssociation `json:"networkInterfaceAssociation,omitempty"`
	SubnetAssociation           *SubnetAssociation    `json:"subnetAssociation,omitempty"`
	// DefaultSecurityRules - Collection of default security rules of the network security group.
	DefaultSecurityRules *[]SecurityRule `json:"defaultSecurityRules,omitempty"`
	// EffectiveSecurityRules - Collection of effective security rules.
	EffectiveSecurityRules *[]EffectiveNetworkSecurityRule `json:"effectiveSecurityRules,omitempty"`
}

// SecurityRuleListResult response for ListSecurityRule API service call. Retrieves all security rules that
// belongs to a network security group.
type SecurityRuleListResult struct {
	autorest.Response `json:"-"`
	// Value - The security rules in a network security group.
	Value *[]SecurityRule `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// SecurityRuleListResultIterator provides access to a complete listing of SecurityRule values.
type SecurityRuleListResultIterator struct {
	i    int
	page SecurityRuleListResultPage
}

// 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 *SecurityRuleListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SecurityRuleListResultIterator.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 *SecurityRuleListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter SecurityRuleListResultIterator) 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 SecurityRuleListResultIterator) Response() SecurityRuleListResult {
	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 SecurityRuleListResultIterator) Value() SecurityRule {
	if !iter.page.NotDone() {
		return SecurityRule{}
	}
	return iter.page.Values()[iter.i]
}

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

// securityRuleListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (srlr SecurityRuleListResult) securityRuleListResultPreparer(ctx context.Context) (*http.Request, error) {
	if srlr.NextLink == nil || len(to.String(srlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(srlr.NextLink)))
}

// SecurityRuleListResultPage contains a page of SecurityRule values.
type SecurityRuleListResultPage struct {
	fn   func(context.Context, SecurityRuleListResult) (SecurityRuleListResult, error)
	srlr SecurityRuleListResult
}

// 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 *SecurityRuleListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SecurityRuleListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.srlr)
	if err != nil {
		return err
	}
	page.srlr = next
	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 *SecurityRuleListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page SecurityRuleListResultPage) Response() SecurityRuleListResult {
	return page.srlr
}

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

// SecurityRulePropertiesFormat security rule resource.
type SecurityRulePropertiesFormat struct {
	// Description - A description for this rule. Restricted to 140 chars.
	Description *string `json:"description,omitempty"`
	// Protocol - Network protocol this rule applies to. Possible values are 'Tcp', 'Udp', and '*'. Possible values include: 'SecurityRuleProtocolTCP', 'SecurityRuleProtocolUDP', 'SecurityRuleProtocolAsterisk'
	Protocol SecurityRuleProtocol `json:"protocol,omitempty"`
	// SourcePortRange - The source port or range. Integer or range between 0 and 65535. Asterix '*' can also be used to match all ports.
	SourcePortRange *string `json:"sourcePortRange,omitempty"`
	// DestinationPortRange - The destination port or range. Integer or range between 0 and 65535. Asterix '*' can also be used to match all ports.
	DestinationPortRange *string `json:"destinationPortRange,omitempty"`
	// SourceAddressPrefix - The CIDR or source IP range. Asterix '*' can also be used to match all source IPs. Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used. If this is an ingress rule, specifies where network traffic originates from.
	SourceAddressPrefix *string `json:"sourceAddressPrefix,omitempty"`
	// SourceAddressPrefixes - The CIDR or source IP ranges.
	SourceAddressPrefixes *[]string `json:"sourceAddressPrefixes,omitempty"`
	// SourceApplicationSecurityGroups - The application security group specified as source.
	SourceApplicationSecurityGroups *[]ApplicationSecurityGroup `json:"sourceApplicationSecurityGroups,omitempty"`
	// DestinationAddressPrefix - The destination address prefix. CIDR or destination IP range. Asterix '*' can also be used to match all source IPs. Default tags such as 'VirtualNetwork', 'AzureLoadBalancer' and 'Internet' can also be used.
	DestinationAddressPrefix *string `json:"destinationAddressPrefix,omitempty"`
	// DestinationAddressPrefixes - The destination address prefixes. CIDR or destination IP ranges.
	DestinationAddressPrefixes *[]string `json:"destinationAddressPrefixes,omitempty"`
	// DestinationApplicationSecurityGroups - The application security group specified as destination.
	DestinationApplicationSecurityGroups *[]ApplicationSecurityGroup `json:"destinationApplicationSecurityGroups,omitempty"`
	// SourcePortRanges - The source port ranges.
	SourcePortRanges *[]string `json:"sourcePortRanges,omitempty"`
	// DestinationPortRanges - The destination port ranges.
	DestinationPortRanges *[]string `json:"destinationPortRanges,omitempty"`
	// Access - The network traffic is allowed or denied. Possible values are: 'Allow' and 'Deny'. Possible values include: 'SecurityRuleAccessAllow', 'SecurityRuleAccessDeny'
	Access SecurityRuleAccess `json:"access,omitempty"`
	// Priority - The priority of the rule. The value can be between 100 and 4096. The priority number must be unique for each rule in the collection. The lower the priority number, the higher the priority of the rule.
	Priority *int32 `json:"priority,omitempty"`
	// Direction - The direction of the rule. The direction specifies if rule will be evaluated on incoming or outcoming traffic. Possible values are: 'Inbound' and 'Outbound'. Possible values include: 'SecurityRuleDirectionInbound', 'SecurityRuleDirectionOutbound'
	Direction SecurityRuleDirection `json:"direction,omitempty"`
	// ProvisioningState - The provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// SecurityRulesCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type SecurityRulesCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SecurityRulesCreateOrUpdateFuture) Result(client SecurityRulesClient) (sr SecurityRule, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SecurityRulesCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if sr.Response.Response, err = future.GetResult(sender); err == nil && sr.Response.Response.StatusCode != http.StatusNoContent {
		sr, err = client.CreateOrUpdateResponder(sr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.SecurityRulesCreateOrUpdateFuture", "Result", sr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// SecurityRulesDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type SecurityRulesDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SecurityRulesDeleteFuture) Result(client SecurityRulesClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SecurityRulesDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SecurityRulesDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// ServiceEndpointPropertiesFormat the service endpoint properties.
type ServiceEndpointPropertiesFormat struct {
	// Service - The type of the endpoint service.
	Service *string `json:"service,omitempty"`
	// Locations - A list of locations.
	Locations *[]string `json:"locations,omitempty"`
	// ProvisioningState - The provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// String ...
type String struct {
	autorest.Response `json:"-"`
	Value             *string `json:"value,omitempty"`
}

// Subnet subnet in a virtual network resource.
type Subnet struct {
	autorest.Response `json:"-"`
	// SubnetPropertiesFormat - Properties of the subnet.
	*SubnetPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for Subnet.
func (s Subnet) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if s.SubnetPropertiesFormat != nil {
		objectMap["properties"] = s.SubnetPropertiesFormat
	}
	if s.Name != nil {
		objectMap["name"] = s.Name
	}
	if s.Etag != nil {
		objectMap["etag"] = s.Etag
	}
	if s.ID != nil {
		objectMap["id"] = s.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Subnet struct.
func (s *Subnet) 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 {
				var subnetPropertiesFormat SubnetPropertiesFormat
				err = json.Unmarshal(*v, &subnetPropertiesFormat)
				if err != nil {
					return err
				}
				s.SubnetPropertiesFormat = &subnetPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				s.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				s.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				s.ID = &ID
			}
		}
	}

	return nil
}

// SubnetAssociation network interface and its custom security rules.
type SubnetAssociation struct {
	// ID - Subnet ID.
	ID *string `json:"id,omitempty"`
	// SecurityRules - Collection of custom security rules.
	SecurityRules *[]SecurityRule `json:"securityRules,omitempty"`
}

// SubnetListResult response for ListSubnets API service callRetrieves all subnet that belongs to a virtual
// network
type SubnetListResult struct {
	autorest.Response `json:"-"`
	// Value - The subnets in a virtual network.
	Value *[]Subnet `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// SubnetListResultIterator provides access to a complete listing of Subnet values.
type SubnetListResultIterator struct {
	i    int
	page SubnetListResultPage
}

// 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 *SubnetListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SubnetListResultIterator.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 *SubnetListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter SubnetListResultIterator) 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 SubnetListResultIterator) Response() SubnetListResult {
	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 SubnetListResultIterator) Value() Subnet {
	if !iter.page.NotDone() {
		return Subnet{}
	}
	return iter.page.Values()[iter.i]
}

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

// subnetListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (slr SubnetListResult) subnetListResultPreparer(ctx context.Context) (*http.Request, error) {
	if slr.NextLink == nil || len(to.String(slr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(slr.NextLink)))
}

// SubnetListResultPage contains a page of Subnet values.
type SubnetListResultPage struct {
	fn  func(context.Context, SubnetListResult) (SubnetListResult, error)
	slr SubnetListResult
}

// 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 *SubnetListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/SubnetListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.slr)
	if err != nil {
		return err
	}
	page.slr = next
	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 *SubnetListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page SubnetListResultPage) Response() SubnetListResult {
	return page.slr
}

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

// SubnetPropertiesFormat properties of the subnet.
type SubnetPropertiesFormat struct {
	// AddressPrefix - The address prefix for the subnet.
	AddressPrefix *string `json:"addressPrefix,omitempty"`
	// NetworkSecurityGroup - The reference of the NetworkSecurityGroup resource.
	NetworkSecurityGroup *SecurityGroup `json:"networkSecurityGroup,omitempty"`
	// RouteTable - The reference of the RouteTable resource.
	RouteTable *RouteTable `json:"routeTable,omitempty"`
	// ServiceEndpoints - An array of service endpoints.
	ServiceEndpoints *[]ServiceEndpointPropertiesFormat `json:"serviceEndpoints,omitempty"`
	// IPConfigurations - Gets an array of references to the network interface IP configurations using subnet.
	IPConfigurations *[]IPConfiguration `json:"ipConfigurations,omitempty"`
	// ResourceNavigationLinks - Gets an array of references to the external resources using subnet.
	ResourceNavigationLinks *[]ResourceNavigationLink `json:"resourceNavigationLinks,omitempty"`
	// ProvisioningState - The provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// SubnetsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type SubnetsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SubnetsCreateOrUpdateFuture) Result(client SubnetsClient) (s Subnet, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SubnetsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent {
		s, err = client.CreateOrUpdateResponder(s.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.SubnetsCreateOrUpdateFuture", "Result", s.Response.Response, "Failure responding to request")
		}
	}
	return
}

// SubnetsDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type SubnetsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *SubnetsDeleteFuture) Result(client SubnetsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.SubnetsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.SubnetsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// SubResource reference to another subresource.
type SubResource struct {
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// TagsObject tags object for patch operations.
type TagsObject struct {
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

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

// Topology topology of the specified resource group.
type Topology struct {
	autorest.Response `json:"-"`
	// ID - GUID representing the operation id.
	ID *string `json:"id,omitempty"`
	// CreatedDateTime - The datetime when the topology was initially created for the resource group.
	CreatedDateTime *date.Time `json:"createdDateTime,omitempty"`
	// LastModified - The datetime when the topology was last modified.
	LastModified *date.Time          `json:"lastModified,omitempty"`
	Resources    *[]TopologyResource `json:"resources,omitempty"`
}

// TopologyAssociation resources that have an association with the parent resource.
type TopologyAssociation struct {
	// Name - The name of the resource that is associated with the parent resource.
	Name *string `json:"name,omitempty"`
	// ResourceID - The ID of the resource that is associated with the parent resource.
	ResourceID *string `json:"resourceId,omitempty"`
	// AssociationType - The association type of the child resource to the parent resource. Possible values include: 'Associated', 'Contains'
	AssociationType AssociationType `json:"associationType,omitempty"`
}

// TopologyParameters parameters that define the representation of topology.
type TopologyParameters struct {
	// TargetResourceGroupName - The name of the target resource group to perform topology on.
	TargetResourceGroupName *string `json:"targetResourceGroupName,omitempty"`
}

// TopologyResource the network resource topology information for the given resource group.
type TopologyResource struct {
	// Name - Name of the resource.
	Name *string `json:"name,omitempty"`
	// ID - ID of the resource.
	ID *string `json:"id,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Associations - Holds the associations the resource has with other resources in the resource group.
	Associations *[]TopologyAssociation `json:"associations,omitempty"`
}

// TroubleshootingDetails information gained from troubleshooting of specified resource.
type TroubleshootingDetails struct {
	// ID - The id of the get troubleshoot operation.
	ID *string `json:"id,omitempty"`
	// ReasonType - Reason type of failure.
	ReasonType *string `json:"reasonType,omitempty"`
	// Summary - A summary of troubleshooting.
	Summary *string `json:"summary,omitempty"`
	// Detail - Details on troubleshooting results.
	Detail *string `json:"detail,omitempty"`
	// RecommendedActions - List of recommended actions.
	RecommendedActions *[]TroubleshootingRecommendedActions `json:"recommendedActions,omitempty"`
}

// TroubleshootingParameters parameters that define the resource to troubleshoot.
type TroubleshootingParameters struct {
	// TargetResourceID - The target resource to troubleshoot.
	TargetResourceID           *string `json:"targetResourceId,omitempty"`
	*TroubleshootingProperties `json:"properties,omitempty"`
}

// MarshalJSON is the custom marshaler for TroubleshootingParameters.
func (tp TroubleshootingParameters) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if tp.TargetResourceID != nil {
		objectMap["targetResourceId"] = tp.TargetResourceID
	}
	if tp.TroubleshootingProperties != nil {
		objectMap["properties"] = tp.TroubleshootingProperties
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for TroubleshootingParameters struct.
func (tp *TroubleshootingParameters) 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 "targetResourceId":
			if v != nil {
				var targetResourceID string
				err = json.Unmarshal(*v, &targetResourceID)
				if err != nil {
					return err
				}
				tp.TargetResourceID = &targetResourceID
			}
		case "properties":
			if v != nil {
				var troubleshootingProperties TroubleshootingProperties
				err = json.Unmarshal(*v, &troubleshootingProperties)
				if err != nil {
					return err
				}
				tp.TroubleshootingProperties = &troubleshootingProperties
			}
		}
	}

	return nil
}

// TroubleshootingProperties storage location provided for troubleshoot.
type TroubleshootingProperties struct {
	// StorageID - The ID for the storage account to save the troubleshoot result.
	StorageID *string `json:"storageId,omitempty"`
	// StoragePath - The path to the blob to save the troubleshoot result in.
	StoragePath *string `json:"storagePath,omitempty"`
}

// TroubleshootingRecommendedActions recommended actions based on discovered issues.
type TroubleshootingRecommendedActions struct {
	// ActionID - ID of the recommended action.
	ActionID *string `json:"actionId,omitempty"`
	// ActionText - Description of recommended actions.
	ActionText *string `json:"actionText,omitempty"`
	// ActionURI - The uri linking to a documentation for the recommended troubleshooting actions.
	ActionURI *string `json:"actionUri,omitempty"`
	// ActionURIText - The information from the URI for the recommended troubleshooting actions.
	ActionURIText *string `json:"actionUriText,omitempty"`
}

// TroubleshootingResult troubleshooting information gained from specified resource.
type TroubleshootingResult struct {
	autorest.Response `json:"-"`
	// StartTime - The start time of the troubleshooting.
	StartTime *date.Time `json:"startTime,omitempty"`
	// EndTime - The end time of the troubleshooting.
	EndTime *date.Time `json:"endTime,omitempty"`
	// Code - The result code of the troubleshooting.
	Code *string `json:"code,omitempty"`
	// Results - Information from troubleshooting.
	Results *[]TroubleshootingDetails `json:"results,omitempty"`
}

// TunnelConnectionHealth virtualNetworkGatewayConnection properties
type TunnelConnectionHealth struct {
	// Tunnel - Tunnel name.
	Tunnel *string `json:"tunnel,omitempty"`
	// ConnectionStatus - Virtual network Gateway connection status. Possible values include: 'VirtualNetworkGatewayConnectionStatusUnknown', 'VirtualNetworkGatewayConnectionStatusConnecting', 'VirtualNetworkGatewayConnectionStatusConnected', 'VirtualNetworkGatewayConnectionStatusNotConnected'
	ConnectionStatus VirtualNetworkGatewayConnectionStatus `json:"connectionStatus,omitempty"`
	// IngressBytesTransferred - The Ingress Bytes Transferred in this connection
	IngressBytesTransferred *int64 `json:"ingressBytesTransferred,omitempty"`
	// EgressBytesTransferred - The Egress Bytes Transferred in this connection
	EgressBytesTransferred *int64 `json:"egressBytesTransferred,omitempty"`
	// LastConnectionEstablishedUtcTime - The time at which connection was established in Utc format.
	LastConnectionEstablishedUtcTime *string `json:"lastConnectionEstablishedUtcTime,omitempty"`
}

// Usage describes network resource usage.
type Usage struct {
	// ID - Resource identifier.
	ID *string `json:"id,omitempty"`
	// Unit - An enum describing the unit of measurement.
	Unit *string `json:"unit,omitempty"`
	// CurrentValue - The current value of the usage.
	CurrentValue *int64 `json:"currentValue,omitempty"`
	// Limit - The limit of usage.
	Limit *int64 `json:"limit,omitempty"`
	// Name - The name of the type of usage.
	Name *UsageName `json:"name,omitempty"`
}

// UsageName the usage names.
type UsageName struct {
	// Value - A string describing the resource name.
	Value *string `json:"value,omitempty"`
	// LocalizedValue - A localized string describing the resource name.
	LocalizedValue *string `json:"localizedValue,omitempty"`
}

// UsagesListResult the list usages operation response.
type UsagesListResult struct {
	autorest.Response `json:"-"`
	// Value - The list network resource usages.
	Value *[]Usage `json:"value,omitempty"`
	// NextLink - URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// UsagesListResultIterator provides access to a complete listing of Usage values.
type UsagesListResultIterator struct {
	i    int
	page UsagesListResultPage
}

// 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 *UsagesListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/UsagesListResultIterator.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 *UsagesListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter UsagesListResultIterator) 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 UsagesListResultIterator) Response() UsagesListResult {
	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 UsagesListResultIterator) Value() Usage {
	if !iter.page.NotDone() {
		return Usage{}
	}
	return iter.page.Values()[iter.i]
}

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

// usagesListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (ulr UsagesListResult) usagesListResultPreparer(ctx context.Context) (*http.Request, error) {
	if ulr.NextLink == nil || len(to.String(ulr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(ulr.NextLink)))
}

// UsagesListResultPage contains a page of Usage values.
type UsagesListResultPage struct {
	fn  func(context.Context, UsagesListResult) (UsagesListResult, error)
	ulr UsagesListResult
}

// 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 *UsagesListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/UsagesListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.ulr)
	if err != nil {
		return err
	}
	page.ulr = next
	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 *UsagesListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page UsagesListResultPage) Response() UsagesListResult {
	return page.ulr
}

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

// VerificationIPFlowParameters parameters that define the IP flow to be verified.
type VerificationIPFlowParameters struct {
	// TargetResourceID - The ID of the target resource to perform next-hop on.
	TargetResourceID *string `json:"targetResourceId,omitempty"`
	// Direction - The direction of the packet represented as a 5-tuple. Possible values include: 'Inbound', 'Outbound'
	Direction Direction `json:"direction,omitempty"`
	// Protocol - Protocol to be verified on. Possible values include: 'ProtocolTCP', 'ProtocolUDP'
	Protocol Protocol `json:"protocol,omitempty"`
	// LocalPort - The local port. Acceptable values are a single integer in the range (0-65535). Support for * for the source port, which depends on the direction.
	LocalPort *string `json:"localPort,omitempty"`
	// RemotePort - The remote port. Acceptable values are a single integer in the range (0-65535). Support for * for the source port, which depends on the direction.
	RemotePort *string `json:"remotePort,omitempty"`
	// LocalIPAddress - The local IP address. Acceptable values are valid IPv4 addresses.
	LocalIPAddress *string `json:"localIPAddress,omitempty"`
	// RemoteIPAddress - The remote IP address. Acceptable values are valid IPv4 addresses.
	RemoteIPAddress *string `json:"remoteIPAddress,omitempty"`
	// TargetNicResourceID - The NIC ID. (If VM has multiple NICs and IP forwarding is enabled on any of them, then this parameter must be specified. Otherwise optional).
	TargetNicResourceID *string `json:"targetNicResourceId,omitempty"`
}

// VerificationIPFlowResult results of IP flow verification on the target resource.
type VerificationIPFlowResult struct {
	autorest.Response `json:"-"`
	// Access - Indicates whether the traffic is allowed or denied. Possible values include: 'Allow', 'Deny'
	Access Access `json:"access,omitempty"`
	// RuleName - Name of the rule. If input is not matched against any security rule, it is not displayed.
	RuleName *string `json:"ruleName,omitempty"`
}

// VirtualNetwork virtual Network resource.
type VirtualNetwork struct {
	autorest.Response `json:"-"`
	// VirtualNetworkPropertiesFormat - Properties of the virtual network.
	*VirtualNetworkPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for VirtualNetwork.
func (vn VirtualNetwork) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vn.VirtualNetworkPropertiesFormat != nil {
		objectMap["properties"] = vn.VirtualNetworkPropertiesFormat
	}
	if vn.Etag != nil {
		objectMap["etag"] = vn.Etag
	}
	if vn.ID != nil {
		objectMap["id"] = vn.ID
	}
	if vn.Name != nil {
		objectMap["name"] = vn.Name
	}
	if vn.Type != nil {
		objectMap["type"] = vn.Type
	}
	if vn.Location != nil {
		objectMap["location"] = vn.Location
	}
	if vn.Tags != nil {
		objectMap["tags"] = vn.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetwork struct.
func (vn *VirtualNetwork) 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 {
				var virtualNetworkPropertiesFormat VirtualNetworkPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkPropertiesFormat)
				if err != nil {
					return err
				}
				vn.VirtualNetworkPropertiesFormat = &virtualNetworkPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vn.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vn.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vn.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				vn.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				vn.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				vn.Tags = tags
			}
		}
	}

	return nil
}

// VirtualNetworkConnectionGatewayReference a reference to VirtualNetworkGateway or LocalNetworkGateway
// resource.
type VirtualNetworkConnectionGatewayReference struct {
	// ID - The ID of VirtualNetworkGateway or LocalNetworkGateway resource.
	ID *string `json:"id,omitempty"`
}

// VirtualNetworkGateway a common class for general resource information
type VirtualNetworkGateway struct {
	autorest.Response `json:"-"`
	// VirtualNetworkGatewayPropertiesFormat - Properties of the virtual network gateway.
	*VirtualNetworkGatewayPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for VirtualNetworkGateway.
func (vng VirtualNetworkGateway) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vng.VirtualNetworkGatewayPropertiesFormat != nil {
		objectMap["properties"] = vng.VirtualNetworkGatewayPropertiesFormat
	}
	if vng.Etag != nil {
		objectMap["etag"] = vng.Etag
	}
	if vng.ID != nil {
		objectMap["id"] = vng.ID
	}
	if vng.Name != nil {
		objectMap["name"] = vng.Name
	}
	if vng.Type != nil {
		objectMap["type"] = vng.Type
	}
	if vng.Location != nil {
		objectMap["location"] = vng.Location
	}
	if vng.Tags != nil {
		objectMap["tags"] = vng.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetworkGateway struct.
func (vng *VirtualNetworkGateway) 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 {
				var virtualNetworkGatewayPropertiesFormat VirtualNetworkGatewayPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkGatewayPropertiesFormat)
				if err != nil {
					return err
				}
				vng.VirtualNetworkGatewayPropertiesFormat = &virtualNetworkGatewayPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vng.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vng.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vng.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				vng.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				vng.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				vng.Tags = tags
			}
		}
	}

	return nil
}

// VirtualNetworkGatewayConnection a common class for general resource information
type VirtualNetworkGatewayConnection struct {
	autorest.Response `json:"-"`
	// VirtualNetworkGatewayConnectionPropertiesFormat - Properties of the virtual network gateway connection.
	*VirtualNetworkGatewayConnectionPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for VirtualNetworkGatewayConnection.
func (vngc VirtualNetworkGatewayConnection) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vngc.VirtualNetworkGatewayConnectionPropertiesFormat != nil {
		objectMap["properties"] = vngc.VirtualNetworkGatewayConnectionPropertiesFormat
	}
	if vngc.Etag != nil {
		objectMap["etag"] = vngc.Etag
	}
	if vngc.ID != nil {
		objectMap["id"] = vngc.ID
	}
	if vngc.Name != nil {
		objectMap["name"] = vngc.Name
	}
	if vngc.Type != nil {
		objectMap["type"] = vngc.Type
	}
	if vngc.Location != nil {
		objectMap["location"] = vngc.Location
	}
	if vngc.Tags != nil {
		objectMap["tags"] = vngc.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetworkGatewayConnection struct.
func (vngc *VirtualNetworkGatewayConnection) 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 {
				var virtualNetworkGatewayConnectionPropertiesFormat VirtualNetworkGatewayConnectionPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkGatewayConnectionPropertiesFormat)
				if err != nil {
					return err
				}
				vngc.VirtualNetworkGatewayConnectionPropertiesFormat = &virtualNetworkGatewayConnectionPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vngc.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vngc.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vngc.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				vngc.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				vngc.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				vngc.Tags = tags
			}
		}
	}

	return nil
}

// VirtualNetworkGatewayConnectionListEntity a common class for general resource information
type VirtualNetworkGatewayConnectionListEntity struct {
	autorest.Response `json:"-"`
	// VirtualNetworkGatewayConnectionListEntityPropertiesFormat - Properties of the virtual network gateway connection.
	*VirtualNetworkGatewayConnectionListEntityPropertiesFormat `json:"properties,omitempty"`
	// Etag - Gets a unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for VirtualNetworkGatewayConnectionListEntity.
func (vngcle VirtualNetworkGatewayConnectionListEntity) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vngcle.VirtualNetworkGatewayConnectionListEntityPropertiesFormat != nil {
		objectMap["properties"] = vngcle.VirtualNetworkGatewayConnectionListEntityPropertiesFormat
	}
	if vngcle.Etag != nil {
		objectMap["etag"] = vngcle.Etag
	}
	if vngcle.ID != nil {
		objectMap["id"] = vngcle.ID
	}
	if vngcle.Name != nil {
		objectMap["name"] = vngcle.Name
	}
	if vngcle.Type != nil {
		objectMap["type"] = vngcle.Type
	}
	if vngcle.Location != nil {
		objectMap["location"] = vngcle.Location
	}
	if vngcle.Tags != nil {
		objectMap["tags"] = vngcle.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetworkGatewayConnectionListEntity struct.
func (vngcle *VirtualNetworkGatewayConnectionListEntity) 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 {
				var virtualNetworkGatewayConnectionListEntityPropertiesFormat VirtualNetworkGatewayConnectionListEntityPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkGatewayConnectionListEntityPropertiesFormat)
				if err != nil {
					return err
				}
				vngcle.VirtualNetworkGatewayConnectionListEntityPropertiesFormat = &virtualNetworkGatewayConnectionListEntityPropertiesFormat
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vngcle.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vngcle.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vngcle.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				vngcle.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				vngcle.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				vngcle.Tags = tags
			}
		}
	}

	return nil
}

// VirtualNetworkGatewayConnectionListEntityPropertiesFormat virtualNetworkGatewayConnection properties
type VirtualNetworkGatewayConnectionListEntityPropertiesFormat struct {
	// AuthorizationKey - The authorizationKey.
	AuthorizationKey *string `json:"authorizationKey,omitempty"`
	// VirtualNetworkGateway1 - The reference to virtual network gateway resource.
	VirtualNetworkGateway1 *VirtualNetworkConnectionGatewayReference `json:"virtualNetworkGateway1,omitempty"`
	// VirtualNetworkGateway2 - The reference to virtual network gateway resource.
	VirtualNetworkGateway2 *VirtualNetworkConnectionGatewayReference `json:"virtualNetworkGateway2,omitempty"`
	// LocalNetworkGateway2 - The reference to local network gateway resource.
	LocalNetworkGateway2 *VirtualNetworkConnectionGatewayReference `json:"localNetworkGateway2,omitempty"`
	// ConnectionType - Gateway connection type. Possible values are: 'Ipsec','Vnet2Vnet','ExpressRoute', and 'VPNClient. Possible values include: 'IPsec', 'Vnet2Vnet', 'ExpressRoute', 'VPNClient'
	ConnectionType VirtualNetworkGatewayConnectionType `json:"connectionType,omitempty"`
	// RoutingWeight - The routing weight.
	RoutingWeight *int32 `json:"routingWeight,omitempty"`
	// SharedKey - The IPSec shared key.
	SharedKey *string `json:"sharedKey,omitempty"`
	// ConnectionStatus - Virtual network Gateway connection status. Possible values are 'Unknown', 'Connecting', 'Connected' and 'NotConnected'. Possible values include: 'VirtualNetworkGatewayConnectionStatusUnknown', 'VirtualNetworkGatewayConnectionStatusConnecting', 'VirtualNetworkGatewayConnectionStatusConnected', 'VirtualNetworkGatewayConnectionStatusNotConnected'
	ConnectionStatus VirtualNetworkGatewayConnectionStatus `json:"connectionStatus,omitempty"`
	// TunnelConnectionStatus - Collection of all tunnels' connection health status.
	TunnelConnectionStatus *[]TunnelConnectionHealth `json:"tunnelConnectionStatus,omitempty"`
	// EgressBytesTransferred - The egress bytes transferred in this connection.
	EgressBytesTransferred *int64 `json:"egressBytesTransferred,omitempty"`
	// IngressBytesTransferred - The ingress bytes transferred in this connection.
	IngressBytesTransferred *int64 `json:"ingressBytesTransferred,omitempty"`
	// Peer - The reference to peerings resource.
	Peer *SubResource `json:"peer,omitempty"`
	// EnableBgp - EnableBgp flag
	EnableBgp *bool `json:"enableBgp,omitempty"`
	// UsePolicyBasedTrafficSelectors - Enable policy-based traffic selectors.
	UsePolicyBasedTrafficSelectors *bool `json:"usePolicyBasedTrafficSelectors,omitempty"`
	// IpsecPolicies - The IPSec Policies to be considered by this connection.
	IpsecPolicies *[]IpsecPolicy `json:"ipsecPolicies,omitempty"`
	// ResourceGUID - The resource GUID property of the VirtualNetworkGatewayConnection resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the VirtualNetworkGatewayConnection resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VirtualNetworkGatewayConnectionListResult response for the ListVirtualNetworkGatewayConnections API
// service call
type VirtualNetworkGatewayConnectionListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of VirtualNetworkGatewayConnection resources that exists in a resource group.
	Value *[]VirtualNetworkGatewayConnection `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkGatewayConnectionListResultIterator provides access to a complete listing of
// VirtualNetworkGatewayConnection values.
type VirtualNetworkGatewayConnectionListResultIterator struct {
	i    int
	page VirtualNetworkGatewayConnectionListResultPage
}

// 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 *VirtualNetworkGatewayConnectionListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayConnectionListResultIterator.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 *VirtualNetworkGatewayConnectionListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkGatewayConnectionListResultIterator) 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 VirtualNetworkGatewayConnectionListResultIterator) Response() VirtualNetworkGatewayConnectionListResult {
	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 VirtualNetworkGatewayConnectionListResultIterator) Value() VirtualNetworkGatewayConnection {
	if !iter.page.NotDone() {
		return VirtualNetworkGatewayConnection{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkGatewayConnectionListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vngclr VirtualNetworkGatewayConnectionListResult) virtualNetworkGatewayConnectionListResultPreparer(ctx context.Context) (*http.Request, error) {
	if vngclr.NextLink == nil || len(to.String(vngclr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vngclr.NextLink)))
}

// VirtualNetworkGatewayConnectionListResultPage contains a page of VirtualNetworkGatewayConnection values.
type VirtualNetworkGatewayConnectionListResultPage struct {
	fn     func(context.Context, VirtualNetworkGatewayConnectionListResult) (VirtualNetworkGatewayConnectionListResult, error)
	vngclr VirtualNetworkGatewayConnectionListResult
}

// 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 *VirtualNetworkGatewayConnectionListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayConnectionListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vngclr)
	if err != nil {
		return err
	}
	page.vngclr = next
	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 *VirtualNetworkGatewayConnectionListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkGatewayConnectionListResultPage) Response() VirtualNetworkGatewayConnectionListResult {
	return page.vngclr
}

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

// VirtualNetworkGatewayConnectionPropertiesFormat virtualNetworkGatewayConnection properties
type VirtualNetworkGatewayConnectionPropertiesFormat struct {
	// AuthorizationKey - The authorizationKey.
	AuthorizationKey *string `json:"authorizationKey,omitempty"`
	// VirtualNetworkGateway1 - The reference to virtual network gateway resource.
	VirtualNetworkGateway1 *VirtualNetworkGateway `json:"virtualNetworkGateway1,omitempty"`
	// VirtualNetworkGateway2 - The reference to virtual network gateway resource.
	VirtualNetworkGateway2 *VirtualNetworkGateway `json:"virtualNetworkGateway2,omitempty"`
	// LocalNetworkGateway2 - The reference to local network gateway resource.
	LocalNetworkGateway2 *LocalNetworkGateway `json:"localNetworkGateway2,omitempty"`
	// ConnectionType - Gateway connection type. Possible values are: 'Ipsec','Vnet2Vnet','ExpressRoute', and 'VPNClient. Possible values include: 'IPsec', 'Vnet2Vnet', 'ExpressRoute', 'VPNClient'
	ConnectionType VirtualNetworkGatewayConnectionType `json:"connectionType,omitempty"`
	// RoutingWeight - The routing weight.
	RoutingWeight *int32 `json:"routingWeight,omitempty"`
	// SharedKey - The IPSec shared key.
	SharedKey *string `json:"sharedKey,omitempty"`
	// ConnectionStatus - Virtual network Gateway connection status. Possible values are 'Unknown', 'Connecting', 'Connected' and 'NotConnected'. Possible values include: 'VirtualNetworkGatewayConnectionStatusUnknown', 'VirtualNetworkGatewayConnectionStatusConnecting', 'VirtualNetworkGatewayConnectionStatusConnected', 'VirtualNetworkGatewayConnectionStatusNotConnected'
	ConnectionStatus VirtualNetworkGatewayConnectionStatus `json:"connectionStatus,omitempty"`
	// TunnelConnectionStatus - Collection of all tunnels' connection health status.
	TunnelConnectionStatus *[]TunnelConnectionHealth `json:"tunnelConnectionStatus,omitempty"`
	// EgressBytesTransferred - The egress bytes transferred in this connection.
	EgressBytesTransferred *int64 `json:"egressBytesTransferred,omitempty"`
	// IngressBytesTransferred - The ingress bytes transferred in this connection.
	IngressBytesTransferred *int64 `json:"ingressBytesTransferred,omitempty"`
	// Peer - The reference to peerings resource.
	Peer *SubResource `json:"peer,omitempty"`
	// EnableBgp - EnableBgp flag
	EnableBgp *bool `json:"enableBgp,omitempty"`
	// UsePolicyBasedTrafficSelectors - Enable policy-based traffic selectors.
	UsePolicyBasedTrafficSelectors *bool `json:"usePolicyBasedTrafficSelectors,omitempty"`
	// IpsecPolicies - The IPSec Policies to be considered by this connection.
	IpsecPolicies *[]IpsecPolicy `json:"ipsecPolicies,omitempty"`
	// ResourceGUID - The resource GUID property of the VirtualNetworkGatewayConnection resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the VirtualNetworkGatewayConnection resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VirtualNetworkGatewayConnectionsCreateOrUpdateFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewayConnectionsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewayConnectionsCreateOrUpdateFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngc VirtualNetworkGatewayConnection, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vngc.Response.Response, err = future.GetResult(sender); err == nil && vngc.Response.Response.StatusCode != http.StatusNoContent {
		vngc, err = client.CreateOrUpdateResponder(vngc.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsCreateOrUpdateFuture", "Result", vngc.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewayConnectionsDeleteFuture an abstraction for monitoring and retrieving the results of
// a long-running operation.
type VirtualNetworkGatewayConnectionsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewayConnectionsDeleteFuture) Result(client VirtualNetworkGatewayConnectionsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// VirtualNetworkGatewayConnectionsResetSharedKeyFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewayConnectionsResetSharedKeyFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewayConnectionsResetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (crsk ConnectionResetSharedKey, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if crsk.Response.Response, err = future.GetResult(sender); err == nil && crsk.Response.Response.StatusCode != http.StatusNoContent {
		crsk, err = client.ResetSharedKeyResponder(crsk.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsResetSharedKeyFuture", "Result", crsk.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewayConnectionsSetSharedKeyFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewayConnectionsSetSharedKeyFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewayConnectionsSetSharedKeyFuture) Result(client VirtualNetworkGatewayConnectionsClient) (csk ConnectionSharedKey, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if csk.Response.Response, err = future.GetResult(sender); err == nil && csk.Response.Response.StatusCode != http.StatusNoContent {
		csk, err = client.SetSharedKeyResponder(csk.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsSetSharedKeyFuture", "Result", csk.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewayConnectionsUpdateTagsFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewayConnectionsUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewayConnectionsUpdateTagsFuture) Result(client VirtualNetworkGatewayConnectionsClient) (vngcle VirtualNetworkGatewayConnectionListEntity, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewayConnectionsUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vngcle.Response.Response, err = future.GetResult(sender); err == nil && vngcle.Response.Response.StatusCode != http.StatusNoContent {
		vngcle, err = client.UpdateTagsResponder(vngcle.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewayConnectionsUpdateTagsFuture", "Result", vngcle.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewayIPConfiguration IP configuration for virtual network gateway
type VirtualNetworkGatewayIPConfiguration struct {
	// VirtualNetworkGatewayIPConfigurationPropertiesFormat - Properties of the virtual network gateway ip configuration.
	*VirtualNetworkGatewayIPConfigurationPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for VirtualNetworkGatewayIPConfiguration.
func (vngic VirtualNetworkGatewayIPConfiguration) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vngic.VirtualNetworkGatewayIPConfigurationPropertiesFormat != nil {
		objectMap["properties"] = vngic.VirtualNetworkGatewayIPConfigurationPropertiesFormat
	}
	if vngic.Name != nil {
		objectMap["name"] = vngic.Name
	}
	if vngic.Etag != nil {
		objectMap["etag"] = vngic.Etag
	}
	if vngic.ID != nil {
		objectMap["id"] = vngic.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetworkGatewayIPConfiguration struct.
func (vngic *VirtualNetworkGatewayIPConfiguration) 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 {
				var virtualNetworkGatewayIPConfigurationPropertiesFormat VirtualNetworkGatewayIPConfigurationPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkGatewayIPConfigurationPropertiesFormat)
				if err != nil {
					return err
				}
				vngic.VirtualNetworkGatewayIPConfigurationPropertiesFormat = &virtualNetworkGatewayIPConfigurationPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vngic.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vngic.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vngic.ID = &ID
			}
		}
	}

	return nil
}

// VirtualNetworkGatewayIPConfigurationPropertiesFormat properties of VirtualNetworkGatewayIPConfiguration
type VirtualNetworkGatewayIPConfigurationPropertiesFormat struct {
	// PrivateIPAllocationMethod - The private IP allocation method. Possible values are: 'Static' and 'Dynamic'. Possible values include: 'Static', 'Dynamic'
	PrivateIPAllocationMethod IPAllocationMethod `json:"privateIPAllocationMethod,omitempty"`
	// Subnet - The reference of the subnet resource.
	Subnet *SubResource `json:"subnet,omitempty"`
	// PublicIPAddress - The reference of the public IP resource.
	PublicIPAddress *SubResource `json:"publicIPAddress,omitempty"`
	// ProvisioningState - The provisioning state of the public IP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VirtualNetworkGatewayListConnectionsResult response for the VirtualNetworkGatewayListConnections API
// service call
type VirtualNetworkGatewayListConnectionsResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of VirtualNetworkGatewayConnection resources that exists in a resource group.
	Value *[]VirtualNetworkGatewayConnectionListEntity `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkGatewayListConnectionsResultIterator provides access to a complete listing of
// VirtualNetworkGatewayConnectionListEntity values.
type VirtualNetworkGatewayListConnectionsResultIterator struct {
	i    int
	page VirtualNetworkGatewayListConnectionsResultPage
}

// 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 *VirtualNetworkGatewayListConnectionsResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayListConnectionsResultIterator.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 *VirtualNetworkGatewayListConnectionsResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkGatewayListConnectionsResultIterator) 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 VirtualNetworkGatewayListConnectionsResultIterator) Response() VirtualNetworkGatewayListConnectionsResult {
	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 VirtualNetworkGatewayListConnectionsResultIterator) Value() VirtualNetworkGatewayConnectionListEntity {
	if !iter.page.NotDone() {
		return VirtualNetworkGatewayConnectionListEntity{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkGatewayListConnectionsResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vnglcr VirtualNetworkGatewayListConnectionsResult) virtualNetworkGatewayListConnectionsResultPreparer(ctx context.Context) (*http.Request, error) {
	if vnglcr.NextLink == nil || len(to.String(vnglcr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vnglcr.NextLink)))
}

// VirtualNetworkGatewayListConnectionsResultPage contains a page of
// VirtualNetworkGatewayConnectionListEntity values.
type VirtualNetworkGatewayListConnectionsResultPage struct {
	fn     func(context.Context, VirtualNetworkGatewayListConnectionsResult) (VirtualNetworkGatewayListConnectionsResult, error)
	vnglcr VirtualNetworkGatewayListConnectionsResult
}

// 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 *VirtualNetworkGatewayListConnectionsResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayListConnectionsResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vnglcr)
	if err != nil {
		return err
	}
	page.vnglcr = next
	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 *VirtualNetworkGatewayListConnectionsResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkGatewayListConnectionsResultPage) Response() VirtualNetworkGatewayListConnectionsResult {
	return page.vnglcr
}

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

// VirtualNetworkGatewayListResult response for the ListVirtualNetworkGateways API service call.
type VirtualNetworkGatewayListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of VirtualNetworkGateway resources that exists in a resource group.
	Value *[]VirtualNetworkGateway `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkGatewayListResultIterator provides access to a complete listing of VirtualNetworkGateway
// values.
type VirtualNetworkGatewayListResultIterator struct {
	i    int
	page VirtualNetworkGatewayListResultPage
}

// 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 *VirtualNetworkGatewayListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayListResultIterator.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 *VirtualNetworkGatewayListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkGatewayListResultIterator) 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 VirtualNetworkGatewayListResultIterator) Response() VirtualNetworkGatewayListResult {
	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 VirtualNetworkGatewayListResultIterator) Value() VirtualNetworkGateway {
	if !iter.page.NotDone() {
		return VirtualNetworkGateway{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkGatewayListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vnglr VirtualNetworkGatewayListResult) virtualNetworkGatewayListResultPreparer(ctx context.Context) (*http.Request, error) {
	if vnglr.NextLink == nil || len(to.String(vnglr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vnglr.NextLink)))
}

// VirtualNetworkGatewayListResultPage contains a page of VirtualNetworkGateway values.
type VirtualNetworkGatewayListResultPage struct {
	fn    func(context.Context, VirtualNetworkGatewayListResult) (VirtualNetworkGatewayListResult, error)
	vnglr VirtualNetworkGatewayListResult
}

// 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 *VirtualNetworkGatewayListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkGatewayListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vnglr)
	if err != nil {
		return err
	}
	page.vnglr = next
	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 *VirtualNetworkGatewayListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkGatewayListResultPage) Response() VirtualNetworkGatewayListResult {
	return page.vnglr
}

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

// VirtualNetworkGatewayPropertiesFormat virtualNetworkGateway properties
type VirtualNetworkGatewayPropertiesFormat struct {
	// IPConfigurations - IP configurations for virtual network gateway.
	IPConfigurations *[]VirtualNetworkGatewayIPConfiguration `json:"ipConfigurations,omitempty"`
	// GatewayType - The type of this virtual network gateway. Possible values are: 'Vpn' and 'ExpressRoute'. Possible values include: 'VirtualNetworkGatewayTypeVpn', 'VirtualNetworkGatewayTypeExpressRoute'
	GatewayType VirtualNetworkGatewayType `json:"gatewayType,omitempty"`
	// VpnType - The type of this virtual network gateway. Possible values are: 'PolicyBased' and 'RouteBased'. Possible values include: 'PolicyBased', 'RouteBased'
	VpnType VpnType `json:"vpnType,omitempty"`
	// EnableBgp - Whether BGP is enabled for this virtual network gateway or not.
	EnableBgp *bool `json:"enableBgp,omitempty"`
	// ActiveActive - ActiveActive flag
	ActiveActive *bool `json:"activeActive,omitempty"`
	// GatewayDefaultSite - The reference of the LocalNetworkGateway resource which represents local network site having default routes. Assign Null value in case of removing existing default site setting.
	GatewayDefaultSite *SubResource `json:"gatewayDefaultSite,omitempty"`
	// Sku - The reference of the VirtualNetworkGatewaySku resource which represents the SKU selected for Virtual network gateway.
	Sku *VirtualNetworkGatewaySku `json:"sku,omitempty"`
	// VpnClientConfiguration - The reference of the VpnClientConfiguration resource which represents the P2S VpnClient configurations.
	VpnClientConfiguration *VpnClientConfiguration `json:"vpnClientConfiguration,omitempty"`
	// BgpSettings - Virtual network gateway's BGP speaker settings.
	BgpSettings *BgpSettings `json:"bgpSettings,omitempty"`
	// ResourceGUID - The resource GUID property of the VirtualNetworkGateway resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the VirtualNetworkGateway resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VirtualNetworkGatewaysCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkGatewaysCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysCreateOrUpdateFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent {
		vng, err = client.CreateOrUpdateResponder(vng.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysCreateOrUpdateFuture", "Result", vng.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkGatewaysDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysDeleteFuture) Result(client VirtualNetworkGatewaysClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// VirtualNetworkGatewaysGeneratevpnclientpackageFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewaysGeneratevpnclientpackageFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGeneratevpnclientpackageFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent {
		s, err = client.GeneratevpnclientpackageResponder(s.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGeneratevpnclientpackageFuture", "Result", s.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysGenerateVpnProfileFuture an abstraction for monitoring and retrieving the results
// of a long-running operation.
type VirtualNetworkGatewaysGenerateVpnProfileFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGenerateVpnProfileFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGenerateVpnProfileFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent {
		s, err = client.GenerateVpnProfileResponder(s.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGenerateVpnProfileFuture", "Result", s.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysGetAdvertisedRoutesFuture an abstraction for monitoring and retrieving the results
// of a long-running operation.
type VirtualNetworkGatewaysGetAdvertisedRoutesFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGetAdvertisedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if grlr.Response.Response, err = future.GetResult(sender); err == nil && grlr.Response.Response.StatusCode != http.StatusNoContent {
		grlr, err = client.GetAdvertisedRoutesResponder(grlr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetAdvertisedRoutesFuture", "Result", grlr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysGetBgpPeerStatusFuture an abstraction for monitoring and retrieving the results of
// a long-running operation.
type VirtualNetworkGatewaysGetBgpPeerStatusFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGetBgpPeerStatusFuture) Result(client VirtualNetworkGatewaysClient) (bpslr BgpPeerStatusListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetBgpPeerStatusFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if bpslr.Response.Response, err = future.GetResult(sender); err == nil && bpslr.Response.Response.StatusCode != http.StatusNoContent {
		bpslr, err = client.GetBgpPeerStatusResponder(bpslr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetBgpPeerStatusFuture", "Result", bpslr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysGetLearnedRoutesFuture an abstraction for monitoring and retrieving the results of
// a long-running operation.
type VirtualNetworkGatewaysGetLearnedRoutesFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGetLearnedRoutesFuture) Result(client VirtualNetworkGatewaysClient) (grlr GatewayRouteListResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetLearnedRoutesFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if grlr.Response.Response, err = future.GetResult(sender); err == nil && grlr.Response.Response.StatusCode != http.StatusNoContent {
		grlr, err = client.GetLearnedRoutesResponder(grlr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetLearnedRoutesFuture", "Result", grlr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysGetVpnProfilePackageURLFuture an abstraction for monitoring and retrieving the
// results of a long-running operation.
type VirtualNetworkGatewaysGetVpnProfilePackageURLFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysGetVpnProfilePackageURLFuture) Result(client VirtualNetworkGatewaysClient) (s String, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if s.Response.Response, err = future.GetResult(sender); err == nil && s.Response.Response.StatusCode != http.StatusNoContent {
		s, err = client.GetVpnProfilePackageURLResponder(s.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysGetVpnProfilePackageURLFuture", "Result", s.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaySku virtualNetworkGatewaySku details
type VirtualNetworkGatewaySku struct {
	// Name - Gateway SKU name. Possible values include: 'VirtualNetworkGatewaySkuNameBasic', 'VirtualNetworkGatewaySkuNameHighPerformance', 'VirtualNetworkGatewaySkuNameStandard', 'VirtualNetworkGatewaySkuNameUltraPerformance', 'VirtualNetworkGatewaySkuNameVpnGw1', 'VirtualNetworkGatewaySkuNameVpnGw2', 'VirtualNetworkGatewaySkuNameVpnGw3'
	Name VirtualNetworkGatewaySkuName `json:"name,omitempty"`
	// Tier - Gateway SKU tier. Possible values include: 'VirtualNetworkGatewaySkuTierBasic', 'VirtualNetworkGatewaySkuTierHighPerformance', 'VirtualNetworkGatewaySkuTierStandard', 'VirtualNetworkGatewaySkuTierUltraPerformance', 'VirtualNetworkGatewaySkuTierVpnGw1', 'VirtualNetworkGatewaySkuTierVpnGw2', 'VirtualNetworkGatewaySkuTierVpnGw3'
	Tier VirtualNetworkGatewaySkuTier `json:"tier,omitempty"`
	// Capacity - The capacity.
	Capacity *int32 `json:"capacity,omitempty"`
}

// VirtualNetworkGatewaysResetFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkGatewaysResetFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysResetFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysResetFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent {
		vng, err = client.ResetResponder(vng.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysResetFuture", "Result", vng.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkGatewaysUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkGatewaysUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkGatewaysUpdateTagsFuture) Result(client VirtualNetworkGatewaysClient) (vng VirtualNetworkGateway, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkGatewaysUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vng.Response.Response, err = future.GetResult(sender); err == nil && vng.Response.Response.StatusCode != http.StatusNoContent {
		vng, err = client.UpdateTagsResponder(vng.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkGatewaysUpdateTagsFuture", "Result", vng.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkListResult response for the ListVirtualNetworks API service call.
type VirtualNetworkListResult struct {
	autorest.Response `json:"-"`
	// Value - Gets a list of VirtualNetwork resources in a resource group.
	Value *[]VirtualNetwork `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkListResultIterator provides access to a complete listing of VirtualNetwork values.
type VirtualNetworkListResultIterator struct {
	i    int
	page VirtualNetworkListResultPage
}

// 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 *VirtualNetworkListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkListResultIterator.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 *VirtualNetworkListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkListResultIterator) 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 VirtualNetworkListResultIterator) Response() VirtualNetworkListResult {
	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 VirtualNetworkListResultIterator) Value() VirtualNetwork {
	if !iter.page.NotDone() {
		return VirtualNetwork{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vnlr VirtualNetworkListResult) virtualNetworkListResultPreparer(ctx context.Context) (*http.Request, error) {
	if vnlr.NextLink == nil || len(to.String(vnlr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vnlr.NextLink)))
}

// VirtualNetworkListResultPage contains a page of VirtualNetwork values.
type VirtualNetworkListResultPage struct {
	fn   func(context.Context, VirtualNetworkListResult) (VirtualNetworkListResult, error)
	vnlr VirtualNetworkListResult
}

// 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 *VirtualNetworkListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vnlr)
	if err != nil {
		return err
	}
	page.vnlr = next
	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 *VirtualNetworkListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkListResultPage) Response() VirtualNetworkListResult {
	return page.vnlr
}

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

// VirtualNetworkListUsageResult response for the virtual networks GetUsage API service call.
type VirtualNetworkListUsageResult struct {
	autorest.Response `json:"-"`
	// Value - VirtualNetwork usage stats.
	Value *[]VirtualNetworkUsage `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkListUsageResultIterator provides access to a complete listing of VirtualNetworkUsage
// values.
type VirtualNetworkListUsageResultIterator struct {
	i    int
	page VirtualNetworkListUsageResultPage
}

// 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 *VirtualNetworkListUsageResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkListUsageResultIterator.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 *VirtualNetworkListUsageResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkListUsageResultIterator) 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 VirtualNetworkListUsageResultIterator) Response() VirtualNetworkListUsageResult {
	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 VirtualNetworkListUsageResultIterator) Value() VirtualNetworkUsage {
	if !iter.page.NotDone() {
		return VirtualNetworkUsage{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkListUsageResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vnlur VirtualNetworkListUsageResult) virtualNetworkListUsageResultPreparer(ctx context.Context) (*http.Request, error) {
	if vnlur.NextLink == nil || len(to.String(vnlur.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vnlur.NextLink)))
}

// VirtualNetworkListUsageResultPage contains a page of VirtualNetworkUsage values.
type VirtualNetworkListUsageResultPage struct {
	fn    func(context.Context, VirtualNetworkListUsageResult) (VirtualNetworkListUsageResult, error)
	vnlur VirtualNetworkListUsageResult
}

// 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 *VirtualNetworkListUsageResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkListUsageResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vnlur)
	if err != nil {
		return err
	}
	page.vnlur = next
	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 *VirtualNetworkListUsageResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkListUsageResultPage) Response() VirtualNetworkListUsageResult {
	return page.vnlur
}

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

// VirtualNetworkPeering peerings in a virtual network resource.
type VirtualNetworkPeering struct {
	autorest.Response `json:"-"`
	// VirtualNetworkPeeringPropertiesFormat - Properties of the virtual network peering.
	*VirtualNetworkPeeringPropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for VirtualNetworkPeering.
func (vnp VirtualNetworkPeering) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vnp.VirtualNetworkPeeringPropertiesFormat != nil {
		objectMap["properties"] = vnp.VirtualNetworkPeeringPropertiesFormat
	}
	if vnp.Name != nil {
		objectMap["name"] = vnp.Name
	}
	if vnp.Etag != nil {
		objectMap["etag"] = vnp.Etag
	}
	if vnp.ID != nil {
		objectMap["id"] = vnp.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VirtualNetworkPeering struct.
func (vnp *VirtualNetworkPeering) 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 {
				var virtualNetworkPeeringPropertiesFormat VirtualNetworkPeeringPropertiesFormat
				err = json.Unmarshal(*v, &virtualNetworkPeeringPropertiesFormat)
				if err != nil {
					return err
				}
				vnp.VirtualNetworkPeeringPropertiesFormat = &virtualNetworkPeeringPropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vnp.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vnp.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vnp.ID = &ID
			}
		}
	}

	return nil
}

// VirtualNetworkPeeringListResult response for ListSubnets API service call. Retrieves all subnets that
// belong to a virtual network.
type VirtualNetworkPeeringListResult struct {
	autorest.Response `json:"-"`
	// Value - The peerings in a virtual network.
	Value *[]VirtualNetworkPeering `json:"value,omitempty"`
	// NextLink - The URL to get the next set of results.
	NextLink *string `json:"nextLink,omitempty"`
}

// VirtualNetworkPeeringListResultIterator provides access to a complete listing of VirtualNetworkPeering
// values.
type VirtualNetworkPeeringListResultIterator struct {
	i    int
	page VirtualNetworkPeeringListResultPage
}

// 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 *VirtualNetworkPeeringListResultIterator) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkPeeringListResultIterator.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 *VirtualNetworkPeeringListResultIterator) Next() error {
	return iter.NextWithContext(context.Background())
}

// NotDone returns true if the enumeration should be started or is not yet complete.
func (iter VirtualNetworkPeeringListResultIterator) 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 VirtualNetworkPeeringListResultIterator) Response() VirtualNetworkPeeringListResult {
	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 VirtualNetworkPeeringListResultIterator) Value() VirtualNetworkPeering {
	if !iter.page.NotDone() {
		return VirtualNetworkPeering{}
	}
	return iter.page.Values()[iter.i]
}

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

// virtualNetworkPeeringListResultPreparer prepares a request to retrieve the next set of results.
// It returns nil if no more results exist.
func (vnplr VirtualNetworkPeeringListResult) virtualNetworkPeeringListResultPreparer(ctx context.Context) (*http.Request, error) {
	if vnplr.NextLink == nil || len(to.String(vnplr.NextLink)) < 1 {
		return nil, nil
	}
	return autorest.Prepare((&http.Request{}).WithContext(ctx),
		autorest.AsJSON(),
		autorest.AsGet(),
		autorest.WithBaseURL(to.String(vnplr.NextLink)))
}

// VirtualNetworkPeeringListResultPage contains a page of VirtualNetworkPeering values.
type VirtualNetworkPeeringListResultPage struct {
	fn    func(context.Context, VirtualNetworkPeeringListResult) (VirtualNetworkPeeringListResult, error)
	vnplr VirtualNetworkPeeringListResult
}

// 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 *VirtualNetworkPeeringListResultPage) NextWithContext(ctx context.Context) (err error) {
	if tracing.IsEnabled() {
		ctx = tracing.StartSpan(ctx, fqdn+"/VirtualNetworkPeeringListResultPage.NextWithContext")
		defer func() {
			sc := -1
			if page.Response().Response.Response != nil {
				sc = page.Response().Response.Response.StatusCode
			}
			tracing.EndSpan(ctx, sc, err)
		}()
	}
	next, err := page.fn(ctx, page.vnplr)
	if err != nil {
		return err
	}
	page.vnplr = next
	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 *VirtualNetworkPeeringListResultPage) Next() error {
	return page.NextWithContext(context.Background())
}

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

// Response returns the raw server response from the last page request.
func (page VirtualNetworkPeeringListResultPage) Response() VirtualNetworkPeeringListResult {
	return page.vnplr
}

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

// VirtualNetworkPeeringPropertiesFormat properties of the virtual network peering.
type VirtualNetworkPeeringPropertiesFormat struct {
	// AllowVirtualNetworkAccess - Whether the VMs in the linked virtual network space would be able to access all the VMs in local Virtual network space.
	AllowVirtualNetworkAccess *bool `json:"allowVirtualNetworkAccess,omitempty"`
	// AllowForwardedTraffic - Whether the forwarded traffic from the VMs in the remote virtual network will be allowed/disallowed.
	AllowForwardedTraffic *bool `json:"allowForwardedTraffic,omitempty"`
	// AllowGatewayTransit - If gateway links can be used in remote virtual networking to link to this virtual network.
	AllowGatewayTransit *bool `json:"allowGatewayTransit,omitempty"`
	// UseRemoteGateways - If remote gateways can be used on this virtual network. If the flag is set to true, and allowGatewayTransit on remote peering is also true, virtual network will use gateways of remote virtual network for transit. Only one peering can have this flag set to true. This flag cannot be set if virtual network already has a gateway.
	UseRemoteGateways *bool `json:"useRemoteGateways,omitempty"`
	// RemoteVirtualNetwork - The reference of the remote virtual network. The remote virtual network can be in the same or different region (preview). See here to register for the preview and learn more (https://docs.microsoft.com/en-us/azure/virtual-network/virtual-network-create-peering).
	RemoteVirtualNetwork *SubResource `json:"remoteVirtualNetwork,omitempty"`
	// RemoteAddressSpace - The reference of the remote virtual network address space.
	RemoteAddressSpace *AddressSpace `json:"remoteAddressSpace,omitempty"`
	// PeeringState - The status of the virtual network peering. Possible values are 'Initiated', 'Connected', and 'Disconnected'. Possible values include: 'Initiated', 'Connected', 'Disconnected'
	PeeringState VirtualNetworkPeeringState `json:"peeringState,omitempty"`
	// ProvisioningState - The provisioning state of the resource.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VirtualNetworkPeeringsCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkPeeringsCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkPeeringsCreateOrUpdateFuture) Result(client VirtualNetworkPeeringsClient) (vnp VirtualNetworkPeering, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vnp.Response.Response, err = future.GetResult(sender); err == nil && vnp.Response.Response.StatusCode != http.StatusNoContent {
		vnp, err = client.CreateOrUpdateResponder(vnp.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsCreateOrUpdateFuture", "Result", vnp.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkPeeringsDeleteFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworkPeeringsDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworkPeeringsDeleteFuture) Result(client VirtualNetworkPeeringsClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworkPeeringsDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworkPeeringsDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// VirtualNetworkPropertiesFormat properties of the virtual network.
type VirtualNetworkPropertiesFormat struct {
	// AddressSpace - The AddressSpace that contains an array of IP address ranges that can be used by subnets.
	AddressSpace *AddressSpace `json:"addressSpace,omitempty"`
	// DhcpOptions - The dhcpOptions that contains an array of DNS servers available to VMs deployed in the virtual network.
	DhcpOptions *DhcpOptions `json:"dhcpOptions,omitempty"`
	// Subnets - A list of subnets in a Virtual Network.
	Subnets *[]Subnet `json:"subnets,omitempty"`
	// VirtualNetworkPeerings - A list of peerings in a Virtual Network.
	VirtualNetworkPeerings *[]VirtualNetworkPeering `json:"virtualNetworkPeerings,omitempty"`
	// ResourceGUID - The resourceGuid property of the Virtual Network resource.
	ResourceGUID *string `json:"resourceGuid,omitempty"`
	// ProvisioningState - The provisioning state of the PublicIP resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
	// EnableDdosProtection - Indicates if DDoS protection is enabled for all the protected resources in a Virtual Network.
	EnableDdosProtection *bool `json:"enableDdosProtection,omitempty"`
	// EnableVMProtection - Indicates if Vm protection is enabled for all the subnets in a Virtual Network.
	EnableVMProtection *bool `json:"enableVmProtection,omitempty"`
}

// VirtualNetworksCreateOrUpdateFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworksCreateOrUpdateFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworksCreateOrUpdateFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksCreateOrUpdateFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vn.Response.Response, err = future.GetResult(sender); err == nil && vn.Response.Response.StatusCode != http.StatusNoContent {
		vn, err = client.CreateOrUpdateResponder(vn.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworksCreateOrUpdateFuture", "Result", vn.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworksDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type VirtualNetworksDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworksDeleteFuture) Result(client VirtualNetworksClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworksDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// VirtualNetworksUpdateTagsFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type VirtualNetworksUpdateTagsFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *VirtualNetworksUpdateTagsFuture) Result(client VirtualNetworksClient) (vn VirtualNetwork, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.VirtualNetworksUpdateTagsFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vn.Response.Response, err = future.GetResult(sender); err == nil && vn.Response.Response.StatusCode != http.StatusNoContent {
		vn, err = client.UpdateTagsResponder(vn.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.VirtualNetworksUpdateTagsFuture", "Result", vn.Response.Response, "Failure responding to request")
		}
	}
	return
}

// VirtualNetworkUsage usage details for subnet.
type VirtualNetworkUsage struct {
	// CurrentValue - Indicates number of IPs used from the Subnet.
	CurrentValue *float64 `json:"currentValue,omitempty"`
	// ID - Subnet identifier.
	ID *string `json:"id,omitempty"`
	// Limit - Indicates the size of the subnet.
	Limit *float64 `json:"limit,omitempty"`
	// Name - The name containing common and localized value for usage.
	Name *VirtualNetworkUsageName `json:"name,omitempty"`
	// Unit - Usage units. Returns 'Count'
	Unit *string `json:"unit,omitempty"`
}

// VirtualNetworkUsageName usage strings container.
type VirtualNetworkUsageName struct {
	// LocalizedValue - Localized subnet size and usage string.
	LocalizedValue *string `json:"localizedValue,omitempty"`
	// Value - Subnet size and usage string.
	Value *string `json:"value,omitempty"`
}

// VpnClientConfiguration vpnClientConfiguration for P2S client.
type VpnClientConfiguration struct {
	// VpnClientAddressPool - The reference of the address space resource which represents Address space for P2S VpnClient.
	VpnClientAddressPool *AddressSpace `json:"vpnClientAddressPool,omitempty"`
	// VpnClientRootCertificates - VpnClientRootCertificate for virtual network gateway.
	VpnClientRootCertificates *[]VpnClientRootCertificate `json:"vpnClientRootCertificates,omitempty"`
	// VpnClientRevokedCertificates - VpnClientRevokedCertificate for Virtual network gateway.
	VpnClientRevokedCertificates *[]VpnClientRevokedCertificate `json:"vpnClientRevokedCertificates,omitempty"`
	// VpnClientProtocols - VpnClientProtocols for Virtual network gateway.
	VpnClientProtocols *[]VpnClientProtocol `json:"vpnClientProtocols,omitempty"`
	// RadiusServerAddress - The radius server address property of the VirtualNetworkGateway resource for vpn client connection.
	RadiusServerAddress *string `json:"radiusServerAddress,omitempty"`
	// RadiusServerSecret - The radius secret property of the VirtualNetworkGateway resource for vpn client connection.
	RadiusServerSecret *string `json:"radiusServerSecret,omitempty"`
}

// VpnClientParameters vpn Client Parameters for package generation
type VpnClientParameters struct {
	// ProcessorArchitecture - VPN client Processor Architecture. Possible values are: 'AMD64' and 'X86'. Possible values include: 'Amd64', 'X86'
	ProcessorArchitecture ProcessorArchitecture `json:"processorArchitecture,omitempty"`
	// AuthenticationMethod - VPN client Authentication Method. Possible values are: 'EAPTLS' and 'EAPMSCHAPv2'. Possible values include: 'EAPTLS', 'EAPMSCHAPv2'
	AuthenticationMethod AuthenticationMethod `json:"authenticationMethod,omitempty"`
	// RadiusServerAuthCertificate - The public certificate data for the radius server authentication certificate as a Base-64 encoded string. Required only if external radius authentication has been configured with EAPTLS authentication.
	RadiusServerAuthCertificate *string `json:"radiusServerAuthCertificate,omitempty"`
	// ClientRootCertificates - A list of client root certificates public certificate data encoded as Base-64 strings. Optional parameter for external radius based authentication with EAPTLS.
	ClientRootCertificates *[]string `json:"clientRootCertificates,omitempty"`
}

// VpnClientRevokedCertificate VPN client revoked certificate of virtual network gateway.
type VpnClientRevokedCertificate struct {
	// VpnClientRevokedCertificatePropertiesFormat - Properties of the vpn client revoked certificate.
	*VpnClientRevokedCertificatePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for VpnClientRevokedCertificate.
func (vcrc VpnClientRevokedCertificate) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vcrc.VpnClientRevokedCertificatePropertiesFormat != nil {
		objectMap["properties"] = vcrc.VpnClientRevokedCertificatePropertiesFormat
	}
	if vcrc.Name != nil {
		objectMap["name"] = vcrc.Name
	}
	if vcrc.Etag != nil {
		objectMap["etag"] = vcrc.Etag
	}
	if vcrc.ID != nil {
		objectMap["id"] = vcrc.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VpnClientRevokedCertificate struct.
func (vcrc *VpnClientRevokedCertificate) 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 {
				var vpnClientRevokedCertificatePropertiesFormat VpnClientRevokedCertificatePropertiesFormat
				err = json.Unmarshal(*v, &vpnClientRevokedCertificatePropertiesFormat)
				if err != nil {
					return err
				}
				vcrc.VpnClientRevokedCertificatePropertiesFormat = &vpnClientRevokedCertificatePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vcrc.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vcrc.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vcrc.ID = &ID
			}
		}
	}

	return nil
}

// VpnClientRevokedCertificatePropertiesFormat properties of the revoked VPN client certificate of virtual
// network gateway.
type VpnClientRevokedCertificatePropertiesFormat struct {
	// Thumbprint - The revoked VPN client certificate thumbprint.
	Thumbprint *string `json:"thumbprint,omitempty"`
	// ProvisioningState - The provisioning state of the VPN client revoked certificate resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VpnClientRootCertificate VPN client root certificate of virtual network gateway
type VpnClientRootCertificate struct {
	// VpnClientRootCertificatePropertiesFormat - Properties of the vpn client root certificate.
	*VpnClientRootCertificatePropertiesFormat `json:"properties,omitempty"`
	// Name - The name of the resource that is unique within a resource group. This name can be used to access the resource.
	Name *string `json:"name,omitempty"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag *string `json:"etag,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
}

// MarshalJSON is the custom marshaler for VpnClientRootCertificate.
func (vcrc VpnClientRootCertificate) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if vcrc.VpnClientRootCertificatePropertiesFormat != nil {
		objectMap["properties"] = vcrc.VpnClientRootCertificatePropertiesFormat
	}
	if vcrc.Name != nil {
		objectMap["name"] = vcrc.Name
	}
	if vcrc.Etag != nil {
		objectMap["etag"] = vcrc.Etag
	}
	if vcrc.ID != nil {
		objectMap["id"] = vcrc.ID
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for VpnClientRootCertificate struct.
func (vcrc *VpnClientRootCertificate) 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 {
				var vpnClientRootCertificatePropertiesFormat VpnClientRootCertificatePropertiesFormat
				err = json.Unmarshal(*v, &vpnClientRootCertificatePropertiesFormat)
				if err != nil {
					return err
				}
				vcrc.VpnClientRootCertificatePropertiesFormat = &vpnClientRootCertificatePropertiesFormat
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				vcrc.Name = &name
			}
		case "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				vcrc.Etag = &etag
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				vcrc.ID = &ID
			}
		}
	}

	return nil
}

// VpnClientRootCertificatePropertiesFormat properties of SSL certificates of application gateway
type VpnClientRootCertificatePropertiesFormat struct {
	// PublicCertData - The certificate public data.
	PublicCertData *string `json:"publicCertData,omitempty"`
	// ProvisioningState - The provisioning state of the VPN client root certificate resource. Possible values are: 'Updating', 'Deleting', and 'Failed'.
	ProvisioningState *string `json:"provisioningState,omitempty"`
}

// VpnDeviceScriptParameters vpn device configuration script generation parameters
type VpnDeviceScriptParameters struct {
	// Vendor - The vendor for the vpn device.
	Vendor *string `json:"vendor,omitempty"`
	// DeviceFamily - The device family for the vpn device.
	DeviceFamily *string `json:"deviceFamily,omitempty"`
	// FirmwareVersion - The firmware version for the vpn device.
	FirmwareVersion *string `json:"firmwareVersion,omitempty"`
}

// Watcher network watcher in a resource group.
type Watcher struct {
	autorest.Response `json:"-"`
	// Etag - A unique read-only string that changes whenever the resource is updated.
	Etag                     *string `json:"etag,omitempty"`
	*WatcherPropertiesFormat `json:"properties,omitempty"`
	// ID - Resource ID.
	ID *string `json:"id,omitempty"`
	// Name - Resource name.
	Name *string `json:"name,omitempty"`
	// Type - Resource type.
	Type *string `json:"type,omitempty"`
	// Location - Resource location.
	Location *string `json:"location,omitempty"`
	// Tags - Resource tags.
	Tags map[string]*string `json:"tags"`
}

// MarshalJSON is the custom marshaler for Watcher.
func (w Watcher) MarshalJSON() ([]byte, error) {
	objectMap := make(map[string]interface{})
	if w.Etag != nil {
		objectMap["etag"] = w.Etag
	}
	if w.WatcherPropertiesFormat != nil {
		objectMap["properties"] = w.WatcherPropertiesFormat
	}
	if w.ID != nil {
		objectMap["id"] = w.ID
	}
	if w.Name != nil {
		objectMap["name"] = w.Name
	}
	if w.Type != nil {
		objectMap["type"] = w.Type
	}
	if w.Location != nil {
		objectMap["location"] = w.Location
	}
	if w.Tags != nil {
		objectMap["tags"] = w.Tags
	}
	return json.Marshal(objectMap)
}

// UnmarshalJSON is the custom unmarshaler for Watcher struct.
func (w *Watcher) 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 "etag":
			if v != nil {
				var etag string
				err = json.Unmarshal(*v, &etag)
				if err != nil {
					return err
				}
				w.Etag = &etag
			}
		case "properties":
			if v != nil {
				var watcherPropertiesFormat WatcherPropertiesFormat
				err = json.Unmarshal(*v, &watcherPropertiesFormat)
				if err != nil {
					return err
				}
				w.WatcherPropertiesFormat = &watcherPropertiesFormat
			}
		case "id":
			if v != nil {
				var ID string
				err = json.Unmarshal(*v, &ID)
				if err != nil {
					return err
				}
				w.ID = &ID
			}
		case "name":
			if v != nil {
				var name string
				err = json.Unmarshal(*v, &name)
				if err != nil {
					return err
				}
				w.Name = &name
			}
		case "type":
			if v != nil {
				var typeVar string
				err = json.Unmarshal(*v, &typeVar)
				if err != nil {
					return err
				}
				w.Type = &typeVar
			}
		case "location":
			if v != nil {
				var location string
				err = json.Unmarshal(*v, &location)
				if err != nil {
					return err
				}
				w.Location = &location
			}
		case "tags":
			if v != nil {
				var tags map[string]*string
				err = json.Unmarshal(*v, &tags)
				if err != nil {
					return err
				}
				w.Tags = tags
			}
		}
	}

	return nil
}

// WatcherListResult list of network watcher resources.
type WatcherListResult struct {
	autorest.Response `json:"-"`
	Value             *[]Watcher `json:"value,omitempty"`
}

// WatcherPropertiesFormat the network watcher properties.
type WatcherPropertiesFormat struct {
	// ProvisioningState - The provisioning state of the resource. Possible values include: 'ProvisioningStateSucceeded', 'ProvisioningStateUpdating', 'ProvisioningStateDeleting', 'ProvisioningStateFailed'
	ProvisioningState ProvisioningState `json:"provisioningState,omitempty"`
}

// WatchersCheckConnectivityFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersCheckConnectivityFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersCheckConnectivityFuture) Result(client WatchersClient) (ci ConnectivityInformation, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersCheckConnectivityFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if ci.Response.Response, err = future.GetResult(sender); err == nil && ci.Response.Response.StatusCode != http.StatusNoContent {
		ci, err = client.CheckConnectivityResponder(ci.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersCheckConnectivityFuture", "Result", ci.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersDeleteFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type WatchersDeleteFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersDeleteFuture) Result(client WatchersClient) (ar autorest.Response, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersDeleteFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersDeleteFuture")
		return
	}
	ar.Response = future.Response()
	return
}

// WatchersGetAzureReachabilityReportFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersGetAzureReachabilityReportFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetAzureReachabilityReportFuture) Result(client WatchersClient) (arr AzureReachabilityReport, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetAzureReachabilityReportFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if arr.Response.Response, err = future.GetResult(sender); err == nil && arr.Response.Response.StatusCode != http.StatusNoContent {
		arr, err = client.GetAzureReachabilityReportResponder(arr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetAzureReachabilityReportFuture", "Result", arr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersGetFlowLogStatusFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersGetFlowLogStatusFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetFlowLogStatusFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetFlowLogStatusFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if fli.Response.Response, err = future.GetResult(sender); err == nil && fli.Response.Response.StatusCode != http.StatusNoContent {
		fli, err = client.GetFlowLogStatusResponder(fli.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetFlowLogStatusFuture", "Result", fli.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersGetNextHopFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type WatchersGetNextHopFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetNextHopFuture) Result(client WatchersClient) (nhr NextHopResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetNextHopFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if nhr.Response.Response, err = future.GetResult(sender); err == nil && nhr.Response.Response.StatusCode != http.StatusNoContent {
		nhr, err = client.GetNextHopResponder(nhr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetNextHopFuture", "Result", nhr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersGetTroubleshootingFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersGetTroubleshootingFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetTroubleshootingFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if tr.Response.Response, err = future.GetResult(sender); err == nil && tr.Response.Response.StatusCode != http.StatusNoContent {
		tr, err = client.GetTroubleshootingResponder(tr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingFuture", "Result", tr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersGetTroubleshootingResultFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersGetTroubleshootingResultFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetTroubleshootingResultFuture) Result(client WatchersClient) (tr TroubleshootingResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetTroubleshootingResultFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if tr.Response.Response, err = future.GetResult(sender); err == nil && tr.Response.Response.StatusCode != http.StatusNoContent {
		tr, err = client.GetTroubleshootingResultResponder(tr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetTroubleshootingResultFuture", "Result", tr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersGetVMSecurityRulesFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersGetVMSecurityRulesFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersGetVMSecurityRulesFuture) Result(client WatchersClient) (sgvr SecurityGroupViewResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersGetVMSecurityRulesFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if sgvr.Response.Response, err = future.GetResult(sender); err == nil && sgvr.Response.Response.StatusCode != http.StatusNoContent {
		sgvr, err = client.GetVMSecurityRulesResponder(sgvr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersGetVMSecurityRulesFuture", "Result", sgvr.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersListAvailableProvidersFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersListAvailableProvidersFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersListAvailableProvidersFuture) Result(client WatchersClient) (apl AvailableProvidersList, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersListAvailableProvidersFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if apl.Response.Response, err = future.GetResult(sender); err == nil && apl.Response.Response.StatusCode != http.StatusNoContent {
		apl, err = client.ListAvailableProvidersResponder(apl.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersListAvailableProvidersFuture", "Result", apl.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersSetFlowLogConfigurationFuture an abstraction for monitoring and retrieving the results of a
// long-running operation.
type WatchersSetFlowLogConfigurationFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersSetFlowLogConfigurationFuture) Result(client WatchersClient) (fli FlowLogInformation, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersSetFlowLogConfigurationFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if fli.Response.Response, err = future.GetResult(sender); err == nil && fli.Response.Response.StatusCode != http.StatusNoContent {
		fli, err = client.SetFlowLogConfigurationResponder(fli.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersSetFlowLogConfigurationFuture", "Result", fli.Response.Response, "Failure responding to request")
		}
	}
	return
}

// WatchersVerifyIPFlowFuture an abstraction for monitoring and retrieving the results of a long-running
// operation.
type WatchersVerifyIPFlowFuture struct {
	azure.Future
}

// Result returns the result of the asynchronous operation.
// If the operation has not completed it will return an error.
func (future *WatchersVerifyIPFlowFuture) Result(client WatchersClient) (vifr VerificationIPFlowResult, err error) {
	var done bool
	done, err = future.Done(client)
	if err != nil {
		err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", future.Response(), "Polling failure")
		return
	}
	if !done {
		err = azure.NewAsyncOpIncompleteError("network.WatchersVerifyIPFlowFuture")
		return
	}
	sender := autorest.DecorateSender(client, autorest.DoRetryForStatusCodes(client.RetryAttempts, client.RetryDuration, autorest.StatusCodesForRetry...))
	if vifr.Response.Response, err = future.GetResult(sender); err == nil && vifr.Response.Response.StatusCode != http.StatusNoContent {
		vifr, err = client.VerifyIPFlowResponder(vifr.Response.Response)
		if err != nil {
			err = autorest.NewErrorWithError(err, "network.WatchersVerifyIPFlowFuture", "Result", vifr.Response.Response, "Failure responding to request")
		}
	}
	return
}
