// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.

package elb

import (
	"fmt"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/awsutil"
	"github.com/aws/aws-sdk-go/aws/request"
	"github.com/aws/aws-sdk-go/private/protocol"
	"github.com/aws/aws-sdk-go/private/protocol/query"
)

const opAddTags = "AddTags"

// AddTagsRequest generates a "aws/request.Request" representing the
// client's request for the AddTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AddTags for more information on using the AddTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AddTagsRequest method.
//    req, resp := client.AddTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/AddTags
func (c *ELB) AddTagsRequest(input *AddTagsInput) (req *request.Request, output *AddTagsOutput) {
	op := &request.Operation{
		Name:       opAddTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AddTagsInput{}
	}

	output = &AddTagsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// AddTags API operation for Elastic Load Balancing.
//
// Adds the specified tags to the specified load balancer. Each load balancer
// can have a maximum of 10 tags.
//
// Each tag consists of a key and an optional value. If a tag with the same
// key is already associated with the load balancer, AddTags updates its value.
//
// For more information, see Tag Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/add-remove-tags.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation AddTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeTooManyTagsException "TooManyTags"
//   The quota for the number of tags that can be assigned to a load balancer
//   has been reached.
//
//   * ErrCodeDuplicateTagKeysException "DuplicateTagKeys"
//   A tag key was specified more than once.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/AddTags
func (c *ELB) AddTags(input *AddTagsInput) (*AddTagsOutput, error) {
	req, out := c.AddTagsRequest(input)
	return out, req.Send()
}

// AddTagsWithContext is the same as AddTags with the addition of
// the ability to pass a context and additional request options.
//
// See AddTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) AddTagsWithContext(ctx aws.Context, input *AddTagsInput, opts ...request.Option) (*AddTagsOutput, error) {
	req, out := c.AddTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opApplySecurityGroupsToLoadBalancer = "ApplySecurityGroupsToLoadBalancer"

// ApplySecurityGroupsToLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the ApplySecurityGroupsToLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ApplySecurityGroupsToLoadBalancer for more information on using the ApplySecurityGroupsToLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ApplySecurityGroupsToLoadBalancerRequest method.
//    req, resp := client.ApplySecurityGroupsToLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ApplySecurityGroupsToLoadBalancer
func (c *ELB) ApplySecurityGroupsToLoadBalancerRequest(input *ApplySecurityGroupsToLoadBalancerInput) (req *request.Request, output *ApplySecurityGroupsToLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opApplySecurityGroupsToLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ApplySecurityGroupsToLoadBalancerInput{}
	}

	output = &ApplySecurityGroupsToLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ApplySecurityGroupsToLoadBalancer API operation for Elastic Load Balancing.
//
// Associates one or more security groups with your load balancer in a virtual
// private cloud (VPC). The specified security groups override the previously
// associated security groups.
//
// For more information, see Security Groups for Load Balancers in a VPC (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-security-groups.html#elb-vpc-security-groups)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation ApplySecurityGroupsToLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
//   * ErrCodeInvalidSecurityGroupException "InvalidSecurityGroup"
//   One or more of the specified security groups do not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ApplySecurityGroupsToLoadBalancer
func (c *ELB) ApplySecurityGroupsToLoadBalancer(input *ApplySecurityGroupsToLoadBalancerInput) (*ApplySecurityGroupsToLoadBalancerOutput, error) {
	req, out := c.ApplySecurityGroupsToLoadBalancerRequest(input)
	return out, req.Send()
}

// ApplySecurityGroupsToLoadBalancerWithContext is the same as ApplySecurityGroupsToLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See ApplySecurityGroupsToLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) ApplySecurityGroupsToLoadBalancerWithContext(ctx aws.Context, input *ApplySecurityGroupsToLoadBalancerInput, opts ...request.Option) (*ApplySecurityGroupsToLoadBalancerOutput, error) {
	req, out := c.ApplySecurityGroupsToLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opAttachLoadBalancerToSubnets = "AttachLoadBalancerToSubnets"

// AttachLoadBalancerToSubnetsRequest generates a "aws/request.Request" representing the
// client's request for the AttachLoadBalancerToSubnets operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See AttachLoadBalancerToSubnets for more information on using the AttachLoadBalancerToSubnets
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the AttachLoadBalancerToSubnetsRequest method.
//    req, resp := client.AttachLoadBalancerToSubnetsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/AttachLoadBalancerToSubnets
func (c *ELB) AttachLoadBalancerToSubnetsRequest(input *AttachLoadBalancerToSubnetsInput) (req *request.Request, output *AttachLoadBalancerToSubnetsOutput) {
	op := &request.Operation{
		Name:       opAttachLoadBalancerToSubnets,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &AttachLoadBalancerToSubnetsInput{}
	}

	output = &AttachLoadBalancerToSubnetsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// AttachLoadBalancerToSubnets API operation for Elastic Load Balancing.
//
// Adds one or more subnets to the set of configured subnets for the specified
// load balancer.
//
// The load balancer evenly distributes requests across all registered subnets.
// For more information, see Add or Remove Subnets for Your Load Balancer in
// a VPC (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-manage-subnets.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation AttachLoadBalancerToSubnets for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
//   * ErrCodeSubnetNotFoundException "SubnetNotFound"
//   One or more of the specified subnets do not exist.
//
//   * ErrCodeInvalidSubnetException "InvalidSubnet"
//   The specified VPC has no associated Internet gateway.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/AttachLoadBalancerToSubnets
func (c *ELB) AttachLoadBalancerToSubnets(input *AttachLoadBalancerToSubnetsInput) (*AttachLoadBalancerToSubnetsOutput, error) {
	req, out := c.AttachLoadBalancerToSubnetsRequest(input)
	return out, req.Send()
}

// AttachLoadBalancerToSubnetsWithContext is the same as AttachLoadBalancerToSubnets with the addition of
// the ability to pass a context and additional request options.
//
// See AttachLoadBalancerToSubnets for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) AttachLoadBalancerToSubnetsWithContext(ctx aws.Context, input *AttachLoadBalancerToSubnetsInput, opts ...request.Option) (*AttachLoadBalancerToSubnetsOutput, error) {
	req, out := c.AttachLoadBalancerToSubnetsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opConfigureHealthCheck = "ConfigureHealthCheck"

// ConfigureHealthCheckRequest generates a "aws/request.Request" representing the
// client's request for the ConfigureHealthCheck operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ConfigureHealthCheck for more information on using the ConfigureHealthCheck
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ConfigureHealthCheckRequest method.
//    req, resp := client.ConfigureHealthCheckRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ConfigureHealthCheck
func (c *ELB) ConfigureHealthCheckRequest(input *ConfigureHealthCheckInput) (req *request.Request, output *ConfigureHealthCheckOutput) {
	op := &request.Operation{
		Name:       opConfigureHealthCheck,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ConfigureHealthCheckInput{}
	}

	output = &ConfigureHealthCheckOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ConfigureHealthCheck API operation for Elastic Load Balancing.
//
// Specifies the health check settings to use when evaluating the health state
// of your EC2 instances.
//
// For more information, see Configure Health Checks for Your Load Balancer
// (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-healthchecks.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation ConfigureHealthCheck for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ConfigureHealthCheck
func (c *ELB) ConfigureHealthCheck(input *ConfigureHealthCheckInput) (*ConfigureHealthCheckOutput, error) {
	req, out := c.ConfigureHealthCheckRequest(input)
	return out, req.Send()
}

// ConfigureHealthCheckWithContext is the same as ConfigureHealthCheck with the addition of
// the ability to pass a context and additional request options.
//
// See ConfigureHealthCheck for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) ConfigureHealthCheckWithContext(ctx aws.Context, input *ConfigureHealthCheckInput, opts ...request.Option) (*ConfigureHealthCheckOutput, error) {
	req, out := c.ConfigureHealthCheckRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateAppCookieStickinessPolicy = "CreateAppCookieStickinessPolicy"

// CreateAppCookieStickinessPolicyRequest generates a "aws/request.Request" representing the
// client's request for the CreateAppCookieStickinessPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateAppCookieStickinessPolicy for more information on using the CreateAppCookieStickinessPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateAppCookieStickinessPolicyRequest method.
//    req, resp := client.CreateAppCookieStickinessPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateAppCookieStickinessPolicy
func (c *ELB) CreateAppCookieStickinessPolicyRequest(input *CreateAppCookieStickinessPolicyInput) (req *request.Request, output *CreateAppCookieStickinessPolicyOutput) {
	op := &request.Operation{
		Name:       opCreateAppCookieStickinessPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateAppCookieStickinessPolicyInput{}
	}

	output = &CreateAppCookieStickinessPolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateAppCookieStickinessPolicy API operation for Elastic Load Balancing.
//
// Generates a stickiness policy with sticky session lifetimes that follow that
// of an application-generated cookie. This policy can be associated only with
// HTTP/HTTPS listeners.
//
// This policy is similar to the policy created by CreateLBCookieStickinessPolicy,
// except that the lifetime of the special Elastic Load Balancing cookie, AWSELB,
// follows the lifetime of the application-generated cookie specified in the
// policy configuration. The load balancer only inserts a new stickiness cookie
// when the application response includes a new application cookie.
//
// If the application cookie is explicitly removed or expires, the session stops
// being sticky until a new application cookie is issued.
//
// For more information, see Application-Controlled Session Stickiness (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html#enable-sticky-sessions-application)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation CreateAppCookieStickinessPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeDuplicatePolicyNameException "DuplicatePolicyName"
//   A policy with the specified name already exists for this load balancer.
//
//   * ErrCodeTooManyPoliciesException "TooManyPolicies"
//   The quota for the number of policies for this load balancer has been reached.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateAppCookieStickinessPolicy
func (c *ELB) CreateAppCookieStickinessPolicy(input *CreateAppCookieStickinessPolicyInput) (*CreateAppCookieStickinessPolicyOutput, error) {
	req, out := c.CreateAppCookieStickinessPolicyRequest(input)
	return out, req.Send()
}

// CreateAppCookieStickinessPolicyWithContext is the same as CreateAppCookieStickinessPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See CreateAppCookieStickinessPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) CreateAppCookieStickinessPolicyWithContext(ctx aws.Context, input *CreateAppCookieStickinessPolicyInput, opts ...request.Option) (*CreateAppCookieStickinessPolicyOutput, error) {
	req, out := c.CreateAppCookieStickinessPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLBCookieStickinessPolicy = "CreateLBCookieStickinessPolicy"

// CreateLBCookieStickinessPolicyRequest generates a "aws/request.Request" representing the
// client's request for the CreateLBCookieStickinessPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLBCookieStickinessPolicy for more information on using the CreateLBCookieStickinessPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLBCookieStickinessPolicyRequest method.
//    req, resp := client.CreateLBCookieStickinessPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLBCookieStickinessPolicy
func (c *ELB) CreateLBCookieStickinessPolicyRequest(input *CreateLBCookieStickinessPolicyInput) (req *request.Request, output *CreateLBCookieStickinessPolicyOutput) {
	op := &request.Operation{
		Name:       opCreateLBCookieStickinessPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLBCookieStickinessPolicyInput{}
	}

	output = &CreateLBCookieStickinessPolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateLBCookieStickinessPolicy API operation for Elastic Load Balancing.
//
// Generates a stickiness policy with sticky session lifetimes controlled by
// the lifetime of the browser (user-agent) or a specified expiration period.
// This policy can be associated only with HTTP/HTTPS listeners.
//
// When a load balancer implements this policy, the load balancer uses a special
// cookie to track the instance for each request. When the load balancer receives
// a request, it first checks to see if this cookie is present in the request.
// If so, the load balancer sends the request to the application server specified
// in the cookie. If not, the load balancer sends the request to a server that
// is chosen based on the existing load-balancing algorithm.
//
// A cookie is inserted into the response for binding subsequent requests from
// the same user to that server. The validity of the cookie is based on the
// cookie expiration time, which is specified in the policy configuration.
//
// For more information, see Duration-Based Session Stickiness (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html#enable-sticky-sessions-duration)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation CreateLBCookieStickinessPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeDuplicatePolicyNameException "DuplicatePolicyName"
//   A policy with the specified name already exists for this load balancer.
//
//   * ErrCodeTooManyPoliciesException "TooManyPolicies"
//   The quota for the number of policies for this load balancer has been reached.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLBCookieStickinessPolicy
func (c *ELB) CreateLBCookieStickinessPolicy(input *CreateLBCookieStickinessPolicyInput) (*CreateLBCookieStickinessPolicyOutput, error) {
	req, out := c.CreateLBCookieStickinessPolicyRequest(input)
	return out, req.Send()
}

// CreateLBCookieStickinessPolicyWithContext is the same as CreateLBCookieStickinessPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLBCookieStickinessPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) CreateLBCookieStickinessPolicyWithContext(ctx aws.Context, input *CreateLBCookieStickinessPolicyInput, opts ...request.Option) (*CreateLBCookieStickinessPolicyOutput, error) {
	req, out := c.CreateLBCookieStickinessPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLoadBalancer = "CreateLoadBalancer"

// CreateLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the CreateLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLoadBalancer for more information on using the CreateLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLoadBalancerRequest method.
//    req, resp := client.CreateLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancer
func (c *ELB) CreateLoadBalancerRequest(input *CreateLoadBalancerInput) (req *request.Request, output *CreateLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opCreateLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLoadBalancerInput{}
	}

	output = &CreateLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// CreateLoadBalancer API operation for Elastic Load Balancing.
//
// Creates a Classic Load Balancer.
//
// You can add listeners, security groups, subnets, and tags when you create
// your load balancer, or you can add them later using CreateLoadBalancerListeners,
// ApplySecurityGroupsToLoadBalancer, AttachLoadBalancerToSubnets, and AddTags.
//
// To describe your current load balancers, see DescribeLoadBalancers. When
// you are finished with a load balancer, you can delete it using DeleteLoadBalancer.
//
// You can create up to 20 load balancers per region per account. You can request
// an increase for the number of load balancers for your account. For more information,
// see Limits for Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-limits.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation CreateLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeDuplicateAccessPointNameException "DuplicateLoadBalancerName"
//   The specified load balancer name already exists for this account.
//
//   * ErrCodeTooManyAccessPointsException "TooManyLoadBalancers"
//   The quota for the number of load balancers has been reached.
//
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified ARN does not refer to a valid SSL certificate in AWS Identity
//   and Access Management (IAM) or AWS Certificate Manager (ACM). Note that if
//   you recently uploaded the certificate to IAM, this error might indicate that
//   the certificate is not fully available yet.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
//   * ErrCodeSubnetNotFoundException "SubnetNotFound"
//   One or more of the specified subnets do not exist.
//
//   * ErrCodeInvalidSubnetException "InvalidSubnet"
//   The specified VPC has no associated Internet gateway.
//
//   * ErrCodeInvalidSecurityGroupException "InvalidSecurityGroup"
//   One or more of the specified security groups do not exist.
//
//   * ErrCodeInvalidSchemeException "InvalidScheme"
//   The specified value for the schema is not valid. You can only specify a scheme
//   for load balancers in a VPC.
//
//   * ErrCodeTooManyTagsException "TooManyTags"
//   The quota for the number of tags that can be assigned to a load balancer
//   has been reached.
//
//   * ErrCodeDuplicateTagKeysException "DuplicateTagKeys"
//   A tag key was specified more than once.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol or signature version is not supported.
//
//   * ErrCodeOperationNotPermittedException "OperationNotPermitted"
//   This operation is not allowed.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancer
func (c *ELB) CreateLoadBalancer(input *CreateLoadBalancerInput) (*CreateLoadBalancerOutput, error) {
	req, out := c.CreateLoadBalancerRequest(input)
	return out, req.Send()
}

// CreateLoadBalancerWithContext is the same as CreateLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) CreateLoadBalancerWithContext(ctx aws.Context, input *CreateLoadBalancerInput, opts ...request.Option) (*CreateLoadBalancerOutput, error) {
	req, out := c.CreateLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLoadBalancerListeners = "CreateLoadBalancerListeners"

// CreateLoadBalancerListenersRequest generates a "aws/request.Request" representing the
// client's request for the CreateLoadBalancerListeners operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLoadBalancerListeners for more information on using the CreateLoadBalancerListeners
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLoadBalancerListenersRequest method.
//    req, resp := client.CreateLoadBalancerListenersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancerListeners
func (c *ELB) CreateLoadBalancerListenersRequest(input *CreateLoadBalancerListenersInput) (req *request.Request, output *CreateLoadBalancerListenersOutput) {
	op := &request.Operation{
		Name:       opCreateLoadBalancerListeners,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLoadBalancerListenersInput{}
	}

	output = &CreateLoadBalancerListenersOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateLoadBalancerListeners API operation for Elastic Load Balancing.
//
// Creates one or more listeners for the specified load balancer. If a listener
// with the specified port does not already exist, it is created; otherwise,
// the properties of the new listener must match the properties of the existing
// listener.
//
// For more information, see Listeners for Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation CreateLoadBalancerListeners for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeDuplicateListenerException "DuplicateListener"
//   A listener already exists for the specified load balancer name and port,
//   but with a different instance port, protocol, or SSL certificate.
//
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified ARN does not refer to a valid SSL certificate in AWS Identity
//   and Access Management (IAM) or AWS Certificate Manager (ACM). Note that if
//   you recently uploaded the certificate to IAM, this error might indicate that
//   the certificate is not fully available yet.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol or signature version is not supported.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancerListeners
func (c *ELB) CreateLoadBalancerListeners(input *CreateLoadBalancerListenersInput) (*CreateLoadBalancerListenersOutput, error) {
	req, out := c.CreateLoadBalancerListenersRequest(input)
	return out, req.Send()
}

// CreateLoadBalancerListenersWithContext is the same as CreateLoadBalancerListeners with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLoadBalancerListeners for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) CreateLoadBalancerListenersWithContext(ctx aws.Context, input *CreateLoadBalancerListenersInput, opts ...request.Option) (*CreateLoadBalancerListenersOutput, error) {
	req, out := c.CreateLoadBalancerListenersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opCreateLoadBalancerPolicy = "CreateLoadBalancerPolicy"

// CreateLoadBalancerPolicyRequest generates a "aws/request.Request" representing the
// client's request for the CreateLoadBalancerPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See CreateLoadBalancerPolicy for more information on using the CreateLoadBalancerPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the CreateLoadBalancerPolicyRequest method.
//    req, resp := client.CreateLoadBalancerPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancerPolicy
func (c *ELB) CreateLoadBalancerPolicyRequest(input *CreateLoadBalancerPolicyInput) (req *request.Request, output *CreateLoadBalancerPolicyOutput) {
	op := &request.Operation{
		Name:       opCreateLoadBalancerPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &CreateLoadBalancerPolicyInput{}
	}

	output = &CreateLoadBalancerPolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// CreateLoadBalancerPolicy API operation for Elastic Load Balancing.
//
// Creates a policy with the specified attributes for the specified load balancer.
//
// Policies are settings that are saved for your load balancer and that can
// be applied to the listener or the application server, depending on the policy
// type.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation CreateLoadBalancerPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodePolicyTypeNotFoundException "PolicyTypeNotFound"
//   One or more of the specified policy types do not exist.
//
//   * ErrCodeDuplicatePolicyNameException "DuplicatePolicyName"
//   A policy with the specified name already exists for this load balancer.
//
//   * ErrCodeTooManyPoliciesException "TooManyPolicies"
//   The quota for the number of policies for this load balancer has been reached.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/CreateLoadBalancerPolicy
func (c *ELB) CreateLoadBalancerPolicy(input *CreateLoadBalancerPolicyInput) (*CreateLoadBalancerPolicyOutput, error) {
	req, out := c.CreateLoadBalancerPolicyRequest(input)
	return out, req.Send()
}

// CreateLoadBalancerPolicyWithContext is the same as CreateLoadBalancerPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See CreateLoadBalancerPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) CreateLoadBalancerPolicyWithContext(ctx aws.Context, input *CreateLoadBalancerPolicyInput, opts ...request.Option) (*CreateLoadBalancerPolicyOutput, error) {
	req, out := c.CreateLoadBalancerPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLoadBalancer = "DeleteLoadBalancer"

// DeleteLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLoadBalancer for more information on using the DeleteLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLoadBalancerRequest method.
//    req, resp := client.DeleteLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancer
func (c *ELB) DeleteLoadBalancerRequest(input *DeleteLoadBalancerInput) (req *request.Request, output *DeleteLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opDeleteLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLoadBalancerInput{}
	}

	output = &DeleteLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteLoadBalancer API operation for Elastic Load Balancing.
//
// Deletes the specified load balancer.
//
// If you are attempting to recreate a load balancer, you must reconfigure all
// settings. The DNS name associated with a deleted load balancer are no longer
// usable. The name and associated DNS record of the deleted load balancer no
// longer exist and traffic sent to any of its IP addresses is no longer delivered
// to your instances.
//
// If the load balancer does not exist or has already been deleted, the call
// to DeleteLoadBalancer still succeeds.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DeleteLoadBalancer for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancer
func (c *ELB) DeleteLoadBalancer(input *DeleteLoadBalancerInput) (*DeleteLoadBalancerOutput, error) {
	req, out := c.DeleteLoadBalancerRequest(input)
	return out, req.Send()
}

// DeleteLoadBalancerWithContext is the same as DeleteLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DeleteLoadBalancerWithContext(ctx aws.Context, input *DeleteLoadBalancerInput, opts ...request.Option) (*DeleteLoadBalancerOutput, error) {
	req, out := c.DeleteLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLoadBalancerListeners = "DeleteLoadBalancerListeners"

// DeleteLoadBalancerListenersRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLoadBalancerListeners operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLoadBalancerListeners for more information on using the DeleteLoadBalancerListeners
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLoadBalancerListenersRequest method.
//    req, resp := client.DeleteLoadBalancerListenersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancerListeners
func (c *ELB) DeleteLoadBalancerListenersRequest(input *DeleteLoadBalancerListenersInput) (req *request.Request, output *DeleteLoadBalancerListenersOutput) {
	op := &request.Operation{
		Name:       opDeleteLoadBalancerListeners,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLoadBalancerListenersInput{}
	}

	output = &DeleteLoadBalancerListenersOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteLoadBalancerListeners API operation for Elastic Load Balancing.
//
// Deletes the specified listeners from the specified load balancer.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DeleteLoadBalancerListeners for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancerListeners
func (c *ELB) DeleteLoadBalancerListeners(input *DeleteLoadBalancerListenersInput) (*DeleteLoadBalancerListenersOutput, error) {
	req, out := c.DeleteLoadBalancerListenersRequest(input)
	return out, req.Send()
}

// DeleteLoadBalancerListenersWithContext is the same as DeleteLoadBalancerListeners with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLoadBalancerListeners for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DeleteLoadBalancerListenersWithContext(ctx aws.Context, input *DeleteLoadBalancerListenersInput, opts ...request.Option) (*DeleteLoadBalancerListenersOutput, error) {
	req, out := c.DeleteLoadBalancerListenersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeleteLoadBalancerPolicy = "DeleteLoadBalancerPolicy"

// DeleteLoadBalancerPolicyRequest generates a "aws/request.Request" representing the
// client's request for the DeleteLoadBalancerPolicy operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeleteLoadBalancerPolicy for more information on using the DeleteLoadBalancerPolicy
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeleteLoadBalancerPolicyRequest method.
//    req, resp := client.DeleteLoadBalancerPolicyRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancerPolicy
func (c *ELB) DeleteLoadBalancerPolicyRequest(input *DeleteLoadBalancerPolicyInput) (req *request.Request, output *DeleteLoadBalancerPolicyOutput) {
	op := &request.Operation{
		Name:       opDeleteLoadBalancerPolicy,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeleteLoadBalancerPolicyInput{}
	}

	output = &DeleteLoadBalancerPolicyOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// DeleteLoadBalancerPolicy API operation for Elastic Load Balancing.
//
// Deletes the specified policy from the specified load balancer. This policy
// must not be enabled for any listeners.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DeleteLoadBalancerPolicy for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeleteLoadBalancerPolicy
func (c *ELB) DeleteLoadBalancerPolicy(input *DeleteLoadBalancerPolicyInput) (*DeleteLoadBalancerPolicyOutput, error) {
	req, out := c.DeleteLoadBalancerPolicyRequest(input)
	return out, req.Send()
}

// DeleteLoadBalancerPolicyWithContext is the same as DeleteLoadBalancerPolicy with the addition of
// the ability to pass a context and additional request options.
//
// See DeleteLoadBalancerPolicy for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DeleteLoadBalancerPolicyWithContext(ctx aws.Context, input *DeleteLoadBalancerPolicyInput, opts ...request.Option) (*DeleteLoadBalancerPolicyOutput, error) {
	req, out := c.DeleteLoadBalancerPolicyRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDeregisterInstancesFromLoadBalancer = "DeregisterInstancesFromLoadBalancer"

// DeregisterInstancesFromLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the DeregisterInstancesFromLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DeregisterInstancesFromLoadBalancer for more information on using the DeregisterInstancesFromLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DeregisterInstancesFromLoadBalancerRequest method.
//    req, resp := client.DeregisterInstancesFromLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeregisterInstancesFromLoadBalancer
func (c *ELB) DeregisterInstancesFromLoadBalancerRequest(input *DeregisterInstancesFromLoadBalancerInput) (req *request.Request, output *DeregisterInstancesFromLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opDeregisterInstancesFromLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DeregisterInstancesFromLoadBalancerInput{}
	}

	output = &DeregisterInstancesFromLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DeregisterInstancesFromLoadBalancer API operation for Elastic Load Balancing.
//
// Deregisters the specified instances from the specified load balancer. After
// the instance is deregistered, it no longer receives traffic from the load
// balancer.
//
// You can use DescribeLoadBalancers to verify that the instance is deregistered
// from the load balancer.
//
// For more information, see Register or De-Register EC2 Instances (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-deregister-register-instances.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DeregisterInstancesFromLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidEndPointException "InvalidInstance"
//   The specified endpoint is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DeregisterInstancesFromLoadBalancer
func (c *ELB) DeregisterInstancesFromLoadBalancer(input *DeregisterInstancesFromLoadBalancerInput) (*DeregisterInstancesFromLoadBalancerOutput, error) {
	req, out := c.DeregisterInstancesFromLoadBalancerRequest(input)
	return out, req.Send()
}

// DeregisterInstancesFromLoadBalancerWithContext is the same as DeregisterInstancesFromLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See DeregisterInstancesFromLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DeregisterInstancesFromLoadBalancerWithContext(ctx aws.Context, input *DeregisterInstancesFromLoadBalancerInput, opts ...request.Option) (*DeregisterInstancesFromLoadBalancerOutput, error) {
	req, out := c.DeregisterInstancesFromLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeAccountLimits = "DescribeAccountLimits"

// DescribeAccountLimitsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeAccountLimits operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeAccountLimits for more information on using the DescribeAccountLimits
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeAccountLimitsRequest method.
//    req, resp := client.DescribeAccountLimitsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeAccountLimits
func (c *ELB) DescribeAccountLimitsRequest(input *DescribeAccountLimitsInput) (req *request.Request, output *DescribeAccountLimitsOutput) {
	op := &request.Operation{
		Name:       opDescribeAccountLimits,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeAccountLimitsInput{}
	}

	output = &DescribeAccountLimitsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeAccountLimits API operation for Elastic Load Balancing.
//
// Describes the current Elastic Load Balancing resource limits for your AWS
// account.
//
// For more information, see Limits for Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-limits.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeAccountLimits for usage and error information.
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeAccountLimits
func (c *ELB) DescribeAccountLimits(input *DescribeAccountLimitsInput) (*DescribeAccountLimitsOutput, error) {
	req, out := c.DescribeAccountLimitsRequest(input)
	return out, req.Send()
}

// DescribeAccountLimitsWithContext is the same as DescribeAccountLimits with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeAccountLimits for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeAccountLimitsWithContext(ctx aws.Context, input *DescribeAccountLimitsInput, opts ...request.Option) (*DescribeAccountLimitsOutput, error) {
	req, out := c.DescribeAccountLimitsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeInstanceHealth = "DescribeInstanceHealth"

// DescribeInstanceHealthRequest generates a "aws/request.Request" representing the
// client's request for the DescribeInstanceHealth operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeInstanceHealth for more information on using the DescribeInstanceHealth
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeInstanceHealthRequest method.
//    req, resp := client.DescribeInstanceHealthRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeInstanceHealth
func (c *ELB) DescribeInstanceHealthRequest(input *DescribeInstanceHealthInput) (req *request.Request, output *DescribeInstanceHealthOutput) {
	op := &request.Operation{
		Name:       opDescribeInstanceHealth,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeInstanceHealthInput{}
	}

	output = &DescribeInstanceHealthOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeInstanceHealth API operation for Elastic Load Balancing.
//
// Describes the state of the specified instances with respect to the specified
// load balancer. If no instances are specified, the call describes the state
// of all instances that are currently registered with the load balancer. If
// instances are specified, their state is returned even if they are no longer
// registered with the load balancer. The state of terminated instances is not
// returned.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeInstanceHealth for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidEndPointException "InvalidInstance"
//   The specified endpoint is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeInstanceHealth
func (c *ELB) DescribeInstanceHealth(input *DescribeInstanceHealthInput) (*DescribeInstanceHealthOutput, error) {
	req, out := c.DescribeInstanceHealthRequest(input)
	return out, req.Send()
}

// DescribeInstanceHealthWithContext is the same as DescribeInstanceHealth with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeInstanceHealth for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeInstanceHealthWithContext(ctx aws.Context, input *DescribeInstanceHealthInput, opts ...request.Option) (*DescribeInstanceHealthOutput, error) {
	req, out := c.DescribeInstanceHealthRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancerAttributes = "DescribeLoadBalancerAttributes"

// DescribeLoadBalancerAttributesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancerAttributes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancerAttributes for more information on using the DescribeLoadBalancerAttributes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancerAttributesRequest method.
//    req, resp := client.DescribeLoadBalancerAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerAttributes
func (c *ELB) DescribeLoadBalancerAttributesRequest(input *DescribeLoadBalancerAttributesInput) (req *request.Request, output *DescribeLoadBalancerAttributesOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancerAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancerAttributesInput{}
	}

	output = &DescribeLoadBalancerAttributesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancerAttributes API operation for Elastic Load Balancing.
//
// Describes the attributes for the specified load balancer.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeLoadBalancerAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeLoadBalancerAttributeNotFoundException "LoadBalancerAttributeNotFound"
//   The specified load balancer attribute does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerAttributes
func (c *ELB) DescribeLoadBalancerAttributes(input *DescribeLoadBalancerAttributesInput) (*DescribeLoadBalancerAttributesOutput, error) {
	req, out := c.DescribeLoadBalancerAttributesRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancerAttributesWithContext is the same as DescribeLoadBalancerAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancerAttributes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeLoadBalancerAttributesWithContext(ctx aws.Context, input *DescribeLoadBalancerAttributesInput, opts ...request.Option) (*DescribeLoadBalancerAttributesOutput, error) {
	req, out := c.DescribeLoadBalancerAttributesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancerPolicies = "DescribeLoadBalancerPolicies"

// DescribeLoadBalancerPoliciesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancerPolicies operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancerPolicies for more information on using the DescribeLoadBalancerPolicies
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancerPoliciesRequest method.
//    req, resp := client.DescribeLoadBalancerPoliciesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerPolicies
func (c *ELB) DescribeLoadBalancerPoliciesRequest(input *DescribeLoadBalancerPoliciesInput) (req *request.Request, output *DescribeLoadBalancerPoliciesOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancerPolicies,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancerPoliciesInput{}
	}

	output = &DescribeLoadBalancerPoliciesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancerPolicies API operation for Elastic Load Balancing.
//
// Describes the specified policies.
//
// If you specify a load balancer name, the action returns the descriptions
// of all policies created for the load balancer. If you specify a policy name
// associated with your load balancer, the action returns the description of
// that policy. If you don't specify a load balancer name, the action returns
// descriptions of the specified sample policies, or descriptions of all sample
// policies. The names of the sample policies have the ELBSample- prefix.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeLoadBalancerPolicies for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodePolicyNotFoundException "PolicyNotFound"
//   One or more of the specified policies do not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerPolicies
func (c *ELB) DescribeLoadBalancerPolicies(input *DescribeLoadBalancerPoliciesInput) (*DescribeLoadBalancerPoliciesOutput, error) {
	req, out := c.DescribeLoadBalancerPoliciesRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancerPoliciesWithContext is the same as DescribeLoadBalancerPolicies with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancerPolicies for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeLoadBalancerPoliciesWithContext(ctx aws.Context, input *DescribeLoadBalancerPoliciesInput, opts ...request.Option) (*DescribeLoadBalancerPoliciesOutput, error) {
	req, out := c.DescribeLoadBalancerPoliciesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancerPolicyTypes = "DescribeLoadBalancerPolicyTypes"

// DescribeLoadBalancerPolicyTypesRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancerPolicyTypes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancerPolicyTypes for more information on using the DescribeLoadBalancerPolicyTypes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancerPolicyTypesRequest method.
//    req, resp := client.DescribeLoadBalancerPolicyTypesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerPolicyTypes
func (c *ELB) DescribeLoadBalancerPolicyTypesRequest(input *DescribeLoadBalancerPolicyTypesInput) (req *request.Request, output *DescribeLoadBalancerPolicyTypesOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancerPolicyTypes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeLoadBalancerPolicyTypesInput{}
	}

	output = &DescribeLoadBalancerPolicyTypesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancerPolicyTypes API operation for Elastic Load Balancing.
//
// Describes the specified load balancer policy types or all load balancer policy
// types.
//
// The description of each type indicates how it can be used. For example, some
// policies can be used only with layer 7 listeners, some policies can be used
// only with layer 4 listeners, and some policies can be used only with your
// EC2 instances.
//
// You can use CreateLoadBalancerPolicy to create a policy configuration for
// any of these policy types. Then, depending on the policy type, use either
// SetLoadBalancerPoliciesOfListener or SetLoadBalancerPoliciesForBackendServer
// to set the policy.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeLoadBalancerPolicyTypes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodePolicyTypeNotFoundException "PolicyTypeNotFound"
//   One or more of the specified policy types do not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancerPolicyTypes
func (c *ELB) DescribeLoadBalancerPolicyTypes(input *DescribeLoadBalancerPolicyTypesInput) (*DescribeLoadBalancerPolicyTypesOutput, error) {
	req, out := c.DescribeLoadBalancerPolicyTypesRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancerPolicyTypesWithContext is the same as DescribeLoadBalancerPolicyTypes with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancerPolicyTypes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeLoadBalancerPolicyTypesWithContext(ctx aws.Context, input *DescribeLoadBalancerPolicyTypesInput, opts ...request.Option) (*DescribeLoadBalancerPolicyTypesOutput, error) {
	req, out := c.DescribeLoadBalancerPolicyTypesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDescribeLoadBalancers = "DescribeLoadBalancers"

// DescribeLoadBalancersRequest generates a "aws/request.Request" representing the
// client's request for the DescribeLoadBalancers operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeLoadBalancers for more information on using the DescribeLoadBalancers
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeLoadBalancersRequest method.
//    req, resp := client.DescribeLoadBalancersRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancers
func (c *ELB) DescribeLoadBalancersRequest(input *DescribeLoadBalancersInput) (req *request.Request, output *DescribeLoadBalancersOutput) {
	op := &request.Operation{
		Name:       opDescribeLoadBalancers,
		HTTPMethod: "POST",
		HTTPPath:   "/",
		Paginator: &request.Paginator{
			InputTokens:     []string{"Marker"},
			OutputTokens:    []string{"NextMarker"},
			LimitToken:      "",
			TruncationToken: "",
		},
	}

	if input == nil {
		input = &DescribeLoadBalancersInput{}
	}

	output = &DescribeLoadBalancersOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeLoadBalancers API operation for Elastic Load Balancing.
//
// Describes the specified the load balancers. If no load balancers are specified,
// the call describes all of your load balancers.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeLoadBalancers for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeDependencyThrottleException "DependencyThrottle"
//   A request made by Elastic Load Balancing to another service exceeds the maximum
//   request rate permitted for your account.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeLoadBalancers
func (c *ELB) DescribeLoadBalancers(input *DescribeLoadBalancersInput) (*DescribeLoadBalancersOutput, error) {
	req, out := c.DescribeLoadBalancersRequest(input)
	return out, req.Send()
}

// DescribeLoadBalancersWithContext is the same as DescribeLoadBalancers with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeLoadBalancers for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeLoadBalancersWithContext(ctx aws.Context, input *DescribeLoadBalancersInput, opts ...request.Option) (*DescribeLoadBalancersOutput, error) {
	req, out := c.DescribeLoadBalancersRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// DescribeLoadBalancersPages iterates over the pages of a DescribeLoadBalancers operation,
// calling the "fn" function with the response data for each page. To stop
// iterating, return false from the fn function.
//
// See DescribeLoadBalancers method for more information on how to use this operation.
//
// Note: This operation can generate multiple requests to a service.
//
//    // Example iterating over at most 3 pages of a DescribeLoadBalancers operation.
//    pageNum := 0
//    err := client.DescribeLoadBalancersPages(params,
//        func(page *DescribeLoadBalancersOutput, lastPage bool) bool {
//            pageNum++
//            fmt.Println(page)
//            return pageNum <= 3
//        })
//
func (c *ELB) DescribeLoadBalancersPages(input *DescribeLoadBalancersInput, fn func(*DescribeLoadBalancersOutput, bool) bool) error {
	return c.DescribeLoadBalancersPagesWithContext(aws.BackgroundContext(), input, fn)
}

// DescribeLoadBalancersPagesWithContext same as DescribeLoadBalancersPages except
// it takes a Context and allows setting request options on the pages.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeLoadBalancersPagesWithContext(ctx aws.Context, input *DescribeLoadBalancersInput, fn func(*DescribeLoadBalancersOutput, bool) bool, opts ...request.Option) error {
	p := request.Pagination{
		NewRequest: func() (*request.Request, error) {
			var inCpy *DescribeLoadBalancersInput
			if input != nil {
				tmp := *input
				inCpy = &tmp
			}
			req, _ := c.DescribeLoadBalancersRequest(inCpy)
			req.SetContext(ctx)
			req.ApplyOptions(opts...)
			return req, nil
		},
	}

	cont := true
	for p.Next() && cont {
		cont = fn(p.Page().(*DescribeLoadBalancersOutput), !p.HasNextPage())
	}
	return p.Err()
}

const opDescribeTags = "DescribeTags"

// DescribeTagsRequest generates a "aws/request.Request" representing the
// client's request for the DescribeTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DescribeTags for more information on using the DescribeTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DescribeTagsRequest method.
//    req, resp := client.DescribeTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeTags
func (c *ELB) DescribeTagsRequest(input *DescribeTagsInput) (req *request.Request, output *DescribeTagsOutput) {
	op := &request.Operation{
		Name:       opDescribeTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DescribeTagsInput{}
	}

	output = &DescribeTagsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DescribeTags API operation for Elastic Load Balancing.
//
// Describes the tags associated with the specified load balancers.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DescribeTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DescribeTags
func (c *ELB) DescribeTags(input *DescribeTagsInput) (*DescribeTagsOutput, error) {
	req, out := c.DescribeTagsRequest(input)
	return out, req.Send()
}

// DescribeTagsWithContext is the same as DescribeTags with the addition of
// the ability to pass a context and additional request options.
//
// See DescribeTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DescribeTagsWithContext(ctx aws.Context, input *DescribeTagsInput, opts ...request.Option) (*DescribeTagsOutput, error) {
	req, out := c.DescribeTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDetachLoadBalancerFromSubnets = "DetachLoadBalancerFromSubnets"

// DetachLoadBalancerFromSubnetsRequest generates a "aws/request.Request" representing the
// client's request for the DetachLoadBalancerFromSubnets operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DetachLoadBalancerFromSubnets for more information on using the DetachLoadBalancerFromSubnets
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DetachLoadBalancerFromSubnetsRequest method.
//    req, resp := client.DetachLoadBalancerFromSubnetsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DetachLoadBalancerFromSubnets
func (c *ELB) DetachLoadBalancerFromSubnetsRequest(input *DetachLoadBalancerFromSubnetsInput) (req *request.Request, output *DetachLoadBalancerFromSubnetsOutput) {
	op := &request.Operation{
		Name:       opDetachLoadBalancerFromSubnets,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DetachLoadBalancerFromSubnetsInput{}
	}

	output = &DetachLoadBalancerFromSubnetsOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DetachLoadBalancerFromSubnets API operation for Elastic Load Balancing.
//
// Removes the specified subnets from the set of configured subnets for the
// load balancer.
//
// After a subnet is removed, all EC2 instances registered with the load balancer
// in the removed subnet go into the OutOfService state. Then, the load balancer
// balances the traffic among the remaining routable subnets.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DetachLoadBalancerFromSubnets for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DetachLoadBalancerFromSubnets
func (c *ELB) DetachLoadBalancerFromSubnets(input *DetachLoadBalancerFromSubnetsInput) (*DetachLoadBalancerFromSubnetsOutput, error) {
	req, out := c.DetachLoadBalancerFromSubnetsRequest(input)
	return out, req.Send()
}

// DetachLoadBalancerFromSubnetsWithContext is the same as DetachLoadBalancerFromSubnets with the addition of
// the ability to pass a context and additional request options.
//
// See DetachLoadBalancerFromSubnets for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DetachLoadBalancerFromSubnetsWithContext(ctx aws.Context, input *DetachLoadBalancerFromSubnetsInput, opts ...request.Option) (*DetachLoadBalancerFromSubnetsOutput, error) {
	req, out := c.DetachLoadBalancerFromSubnetsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opDisableAvailabilityZonesForLoadBalancer = "DisableAvailabilityZonesForLoadBalancer"

// DisableAvailabilityZonesForLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the DisableAvailabilityZonesForLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See DisableAvailabilityZonesForLoadBalancer for more information on using the DisableAvailabilityZonesForLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the DisableAvailabilityZonesForLoadBalancerRequest method.
//    req, resp := client.DisableAvailabilityZonesForLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DisableAvailabilityZonesForLoadBalancer
func (c *ELB) DisableAvailabilityZonesForLoadBalancerRequest(input *DisableAvailabilityZonesForLoadBalancerInput) (req *request.Request, output *DisableAvailabilityZonesForLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opDisableAvailabilityZonesForLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &DisableAvailabilityZonesForLoadBalancerInput{}
	}

	output = &DisableAvailabilityZonesForLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// DisableAvailabilityZonesForLoadBalancer API operation for Elastic Load Balancing.
//
// Removes the specified Availability Zones from the set of Availability Zones
// for the specified load balancer in EC2-Classic or a default VPC.
//
// For load balancers in a non-default VPC, use DetachLoadBalancerFromSubnets.
//
// There must be at least one Availability Zone registered with a load balancer
// at all times. After an Availability Zone is removed, all instances registered
// with the load balancer that are in the removed Availability Zone go into
// the OutOfService state. Then, the load balancer attempts to equally balance
// the traffic among its remaining Availability Zones.
//
// For more information, see Add or Remove Availability Zones (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-disable-az.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation DisableAvailabilityZonesForLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/DisableAvailabilityZonesForLoadBalancer
func (c *ELB) DisableAvailabilityZonesForLoadBalancer(input *DisableAvailabilityZonesForLoadBalancerInput) (*DisableAvailabilityZonesForLoadBalancerOutput, error) {
	req, out := c.DisableAvailabilityZonesForLoadBalancerRequest(input)
	return out, req.Send()
}

// DisableAvailabilityZonesForLoadBalancerWithContext is the same as DisableAvailabilityZonesForLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See DisableAvailabilityZonesForLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) DisableAvailabilityZonesForLoadBalancerWithContext(ctx aws.Context, input *DisableAvailabilityZonesForLoadBalancerInput, opts ...request.Option) (*DisableAvailabilityZonesForLoadBalancerOutput, error) {
	req, out := c.DisableAvailabilityZonesForLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opEnableAvailabilityZonesForLoadBalancer = "EnableAvailabilityZonesForLoadBalancer"

// EnableAvailabilityZonesForLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the EnableAvailabilityZonesForLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See EnableAvailabilityZonesForLoadBalancer for more information on using the EnableAvailabilityZonesForLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the EnableAvailabilityZonesForLoadBalancerRequest method.
//    req, resp := client.EnableAvailabilityZonesForLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/EnableAvailabilityZonesForLoadBalancer
func (c *ELB) EnableAvailabilityZonesForLoadBalancerRequest(input *EnableAvailabilityZonesForLoadBalancerInput) (req *request.Request, output *EnableAvailabilityZonesForLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opEnableAvailabilityZonesForLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &EnableAvailabilityZonesForLoadBalancerInput{}
	}

	output = &EnableAvailabilityZonesForLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// EnableAvailabilityZonesForLoadBalancer API operation for Elastic Load Balancing.
//
// Adds the specified Availability Zones to the set of Availability Zones for
// the specified load balancer in EC2-Classic or a default VPC.
//
// For load balancers in a non-default VPC, use AttachLoadBalancerToSubnets.
//
// The load balancer evenly distributes requests across all its registered Availability
// Zones that contain instances. For more information, see Add or Remove Availability
// Zones (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-disable-az.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation EnableAvailabilityZonesForLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/EnableAvailabilityZonesForLoadBalancer
func (c *ELB) EnableAvailabilityZonesForLoadBalancer(input *EnableAvailabilityZonesForLoadBalancerInput) (*EnableAvailabilityZonesForLoadBalancerOutput, error) {
	req, out := c.EnableAvailabilityZonesForLoadBalancerRequest(input)
	return out, req.Send()
}

// EnableAvailabilityZonesForLoadBalancerWithContext is the same as EnableAvailabilityZonesForLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See EnableAvailabilityZonesForLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) EnableAvailabilityZonesForLoadBalancerWithContext(ctx aws.Context, input *EnableAvailabilityZonesForLoadBalancerInput, opts ...request.Option) (*EnableAvailabilityZonesForLoadBalancerOutput, error) {
	req, out := c.EnableAvailabilityZonesForLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opModifyLoadBalancerAttributes = "ModifyLoadBalancerAttributes"

// ModifyLoadBalancerAttributesRequest generates a "aws/request.Request" representing the
// client's request for the ModifyLoadBalancerAttributes operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See ModifyLoadBalancerAttributes for more information on using the ModifyLoadBalancerAttributes
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the ModifyLoadBalancerAttributesRequest method.
//    req, resp := client.ModifyLoadBalancerAttributesRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ModifyLoadBalancerAttributes
func (c *ELB) ModifyLoadBalancerAttributesRequest(input *ModifyLoadBalancerAttributesInput) (req *request.Request, output *ModifyLoadBalancerAttributesOutput) {
	op := &request.Operation{
		Name:       opModifyLoadBalancerAttributes,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &ModifyLoadBalancerAttributesInput{}
	}

	output = &ModifyLoadBalancerAttributesOutput{}
	req = c.newRequest(op, input, output)
	return
}

// ModifyLoadBalancerAttributes API operation for Elastic Load Balancing.
//
// Modifies the attributes of the specified load balancer.
//
// You can modify the load balancer attributes, such as AccessLogs, ConnectionDraining,
// and CrossZoneLoadBalancing by either enabling or disabling them. Or, you
// can modify the load balancer attribute ConnectionSettings by specifying an
// idle connection timeout value for your load balancer.
//
// For more information, see the following in the Classic Load Balancers Guide:
//
//    * Cross-Zone Load Balancing (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-disable-crosszone-lb.html)
//
//    * Connection Draining (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-conn-drain.html)
//
//    * Access Logs (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/access-log-collection.html)
//
//    * Idle Connection Timeout (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-idle-timeout.html)
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation ModifyLoadBalancerAttributes for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeLoadBalancerAttributeNotFoundException "LoadBalancerAttributeNotFound"
//   The specified load balancer attribute does not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/ModifyLoadBalancerAttributes
func (c *ELB) ModifyLoadBalancerAttributes(input *ModifyLoadBalancerAttributesInput) (*ModifyLoadBalancerAttributesOutput, error) {
	req, out := c.ModifyLoadBalancerAttributesRequest(input)
	return out, req.Send()
}

// ModifyLoadBalancerAttributesWithContext is the same as ModifyLoadBalancerAttributes with the addition of
// the ability to pass a context and additional request options.
//
// See ModifyLoadBalancerAttributes for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) ModifyLoadBalancerAttributesWithContext(ctx aws.Context, input *ModifyLoadBalancerAttributesInput, opts ...request.Option) (*ModifyLoadBalancerAttributesOutput, error) {
	req, out := c.ModifyLoadBalancerAttributesRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRegisterInstancesWithLoadBalancer = "RegisterInstancesWithLoadBalancer"

// RegisterInstancesWithLoadBalancerRequest generates a "aws/request.Request" representing the
// client's request for the RegisterInstancesWithLoadBalancer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See RegisterInstancesWithLoadBalancer for more information on using the RegisterInstancesWithLoadBalancer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the RegisterInstancesWithLoadBalancerRequest method.
//    req, resp := client.RegisterInstancesWithLoadBalancerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/RegisterInstancesWithLoadBalancer
func (c *ELB) RegisterInstancesWithLoadBalancerRequest(input *RegisterInstancesWithLoadBalancerInput) (req *request.Request, output *RegisterInstancesWithLoadBalancerOutput) {
	op := &request.Operation{
		Name:       opRegisterInstancesWithLoadBalancer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RegisterInstancesWithLoadBalancerInput{}
	}

	output = &RegisterInstancesWithLoadBalancerOutput{}
	req = c.newRequest(op, input, output)
	return
}

// RegisterInstancesWithLoadBalancer API operation for Elastic Load Balancing.
//
// Adds the specified instances to the specified load balancer.
//
// The instance must be a running instance in the same network as the load balancer
// (EC2-Classic or the same VPC). If you have EC2-Classic instances and a load
// balancer in a VPC with ClassicLink enabled, you can link the EC2-Classic
// instances to that VPC and then register the linked EC2-Classic instances
// with the load balancer in the VPC.
//
// Note that RegisterInstanceWithLoadBalancer completes when the request has
// been registered. Instance registration takes a little time to complete. To
// check the state of the registered instances, use DescribeLoadBalancers or
// DescribeInstanceHealth.
//
// After the instance is registered, it starts receiving traffic and requests
// from the load balancer. Any instance that is not in one of the Availability
// Zones registered for the load balancer is moved to the OutOfService state.
// If an Availability Zone is added to the load balancer later, any instances
// registered with the load balancer move to the InService state.
//
// To deregister instances from a load balancer, use DeregisterInstancesFromLoadBalancer.
//
// For more information, see Register or De-Register EC2 Instances (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-deregister-register-instances.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation RegisterInstancesWithLoadBalancer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeInvalidEndPointException "InvalidInstance"
//   The specified endpoint is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/RegisterInstancesWithLoadBalancer
func (c *ELB) RegisterInstancesWithLoadBalancer(input *RegisterInstancesWithLoadBalancerInput) (*RegisterInstancesWithLoadBalancerOutput, error) {
	req, out := c.RegisterInstancesWithLoadBalancerRequest(input)
	return out, req.Send()
}

// RegisterInstancesWithLoadBalancerWithContext is the same as RegisterInstancesWithLoadBalancer with the addition of
// the ability to pass a context and additional request options.
//
// See RegisterInstancesWithLoadBalancer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) RegisterInstancesWithLoadBalancerWithContext(ctx aws.Context, input *RegisterInstancesWithLoadBalancerInput, opts ...request.Option) (*RegisterInstancesWithLoadBalancerOutput, error) {
	req, out := c.RegisterInstancesWithLoadBalancerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opRemoveTags = "RemoveTags"

// RemoveTagsRequest generates a "aws/request.Request" representing the
// client's request for the RemoveTags operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See RemoveTags for more information on using the RemoveTags
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the RemoveTagsRequest method.
//    req, resp := client.RemoveTagsRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/RemoveTags
func (c *ELB) RemoveTagsRequest(input *RemoveTagsInput) (req *request.Request, output *RemoveTagsOutput) {
	op := &request.Operation{
		Name:       opRemoveTags,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &RemoveTagsInput{}
	}

	output = &RemoveTagsOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// RemoveTags API operation for Elastic Load Balancing.
//
// Removes one or more tags from the specified load balancer.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation RemoveTags for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/RemoveTags
func (c *ELB) RemoveTags(input *RemoveTagsInput) (*RemoveTagsOutput, error) {
	req, out := c.RemoveTagsRequest(input)
	return out, req.Send()
}

// RemoveTagsWithContext is the same as RemoveTags with the addition of
// the ability to pass a context and additional request options.
//
// See RemoveTags for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) RemoveTagsWithContext(ctx aws.Context, input *RemoveTagsInput, opts ...request.Option) (*RemoveTagsOutput, error) {
	req, out := c.RemoveTagsRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetLoadBalancerListenerSSLCertificate = "SetLoadBalancerListenerSSLCertificate"

// SetLoadBalancerListenerSSLCertificateRequest generates a "aws/request.Request" representing the
// client's request for the SetLoadBalancerListenerSSLCertificate operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetLoadBalancerListenerSSLCertificate for more information on using the SetLoadBalancerListenerSSLCertificate
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetLoadBalancerListenerSSLCertificateRequest method.
//    req, resp := client.SetLoadBalancerListenerSSLCertificateRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerListenerSSLCertificate
func (c *ELB) SetLoadBalancerListenerSSLCertificateRequest(input *SetLoadBalancerListenerSSLCertificateInput) (req *request.Request, output *SetLoadBalancerListenerSSLCertificateOutput) {
	op := &request.Operation{
		Name:       opSetLoadBalancerListenerSSLCertificate,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetLoadBalancerListenerSSLCertificateInput{}
	}

	output = &SetLoadBalancerListenerSSLCertificateOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetLoadBalancerListenerSSLCertificate API operation for Elastic Load Balancing.
//
// Sets the certificate that terminates the specified listener's SSL connections.
// The specified certificate replaces any prior certificate that was used on
// the same load balancer and port.
//
// For more information about updating your SSL certificate, see Replace the
// SSL Certificate for Your Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-update-ssl-cert.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation SetLoadBalancerListenerSSLCertificate for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeCertificateNotFoundException "CertificateNotFound"
//   The specified ARN does not refer to a valid SSL certificate in AWS Identity
//   and Access Management (IAM) or AWS Certificate Manager (ACM). Note that if
//   you recently uploaded the certificate to IAM, this error might indicate that
//   the certificate is not fully available yet.
//
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The load balancer does not have a listener configured at the specified port.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
//   * ErrCodeUnsupportedProtocolException "UnsupportedProtocol"
//   The specified protocol or signature version is not supported.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerListenerSSLCertificate
func (c *ELB) SetLoadBalancerListenerSSLCertificate(input *SetLoadBalancerListenerSSLCertificateInput) (*SetLoadBalancerListenerSSLCertificateOutput, error) {
	req, out := c.SetLoadBalancerListenerSSLCertificateRequest(input)
	return out, req.Send()
}

// SetLoadBalancerListenerSSLCertificateWithContext is the same as SetLoadBalancerListenerSSLCertificate with the addition of
// the ability to pass a context and additional request options.
//
// See SetLoadBalancerListenerSSLCertificate for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) SetLoadBalancerListenerSSLCertificateWithContext(ctx aws.Context, input *SetLoadBalancerListenerSSLCertificateInput, opts ...request.Option) (*SetLoadBalancerListenerSSLCertificateOutput, error) {
	req, out := c.SetLoadBalancerListenerSSLCertificateRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetLoadBalancerPoliciesForBackendServer = "SetLoadBalancerPoliciesForBackendServer"

// SetLoadBalancerPoliciesForBackendServerRequest generates a "aws/request.Request" representing the
// client's request for the SetLoadBalancerPoliciesForBackendServer operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetLoadBalancerPoliciesForBackendServer for more information on using the SetLoadBalancerPoliciesForBackendServer
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetLoadBalancerPoliciesForBackendServerRequest method.
//    req, resp := client.SetLoadBalancerPoliciesForBackendServerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerPoliciesForBackendServer
func (c *ELB) SetLoadBalancerPoliciesForBackendServerRequest(input *SetLoadBalancerPoliciesForBackendServerInput) (req *request.Request, output *SetLoadBalancerPoliciesForBackendServerOutput) {
	op := &request.Operation{
		Name:       opSetLoadBalancerPoliciesForBackendServer,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetLoadBalancerPoliciesForBackendServerInput{}
	}

	output = &SetLoadBalancerPoliciesForBackendServerOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetLoadBalancerPoliciesForBackendServer API operation for Elastic Load Balancing.
//
// Replaces the set of policies associated with the specified port on which
// the EC2 instance is listening with a new set of policies. At this time, only
// the back-end server authentication policy type can be applied to the instance
// ports; this policy type is composed of multiple public key policies.
//
// Each time you use SetLoadBalancerPoliciesForBackendServer to enable the policies,
// use the PolicyNames parameter to list the policies that you want to enable.
//
// You can use DescribeLoadBalancers or DescribeLoadBalancerPolicies to verify
// that the policy is associated with the EC2 instance.
//
// For more information about enabling back-end instance authentication, see
// Configure Back-end Instance Authentication (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-create-https-ssl-load-balancer.html#configure_backendauth_clt)
// in the Classic Load Balancers Guide. For more information about Proxy Protocol,
// see Configure Proxy Protocol Support (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-proxy-protocol.html)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation SetLoadBalancerPoliciesForBackendServer for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodePolicyNotFoundException "PolicyNotFound"
//   One or more of the specified policies do not exist.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerPoliciesForBackendServer
func (c *ELB) SetLoadBalancerPoliciesForBackendServer(input *SetLoadBalancerPoliciesForBackendServerInput) (*SetLoadBalancerPoliciesForBackendServerOutput, error) {
	req, out := c.SetLoadBalancerPoliciesForBackendServerRequest(input)
	return out, req.Send()
}

// SetLoadBalancerPoliciesForBackendServerWithContext is the same as SetLoadBalancerPoliciesForBackendServer with the addition of
// the ability to pass a context and additional request options.
//
// See SetLoadBalancerPoliciesForBackendServer for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) SetLoadBalancerPoliciesForBackendServerWithContext(ctx aws.Context, input *SetLoadBalancerPoliciesForBackendServerInput, opts ...request.Option) (*SetLoadBalancerPoliciesForBackendServerOutput, error) {
	req, out := c.SetLoadBalancerPoliciesForBackendServerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

const opSetLoadBalancerPoliciesOfListener = "SetLoadBalancerPoliciesOfListener"

// SetLoadBalancerPoliciesOfListenerRequest generates a "aws/request.Request" representing the
// client's request for the SetLoadBalancerPoliciesOfListener operation. The "output" return
// value will be populated with the request's response once the request completes
// successfully.
//
// Use "Send" method on the returned Request to send the API call to the service.
// the "output" return value is not valid until after Send returns without error.
//
// See SetLoadBalancerPoliciesOfListener for more information on using the SetLoadBalancerPoliciesOfListener
// API call, and error handling.
//
// This method is useful when you want to inject custom logic or configuration
// into the SDK's request lifecycle. Such as custom headers, or retry logic.
//
//
//    // Example sending a request using the SetLoadBalancerPoliciesOfListenerRequest method.
//    req, resp := client.SetLoadBalancerPoliciesOfListenerRequest(params)
//
//    err := req.Send()
//    if err == nil { // resp is now filled
//        fmt.Println(resp)
//    }
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerPoliciesOfListener
func (c *ELB) SetLoadBalancerPoliciesOfListenerRequest(input *SetLoadBalancerPoliciesOfListenerInput) (req *request.Request, output *SetLoadBalancerPoliciesOfListenerOutput) {
	op := &request.Operation{
		Name:       opSetLoadBalancerPoliciesOfListener,
		HTTPMethod: "POST",
		HTTPPath:   "/",
	}

	if input == nil {
		input = &SetLoadBalancerPoliciesOfListenerInput{}
	}

	output = &SetLoadBalancerPoliciesOfListenerOutput{}
	req = c.newRequest(op, input, output)
	req.Handlers.Unmarshal.Swap(query.UnmarshalHandler.Name, protocol.UnmarshalDiscardBodyHandler)
	return
}

// SetLoadBalancerPoliciesOfListener API operation for Elastic Load Balancing.
//
// Replaces the current set of policies for the specified load balancer port
// with the specified set of policies.
//
// To enable back-end server authentication, use SetLoadBalancerPoliciesForBackendServer.
//
// For more information about setting policies, see Update the SSL Negotiation
// Configuration (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/ssl-config-update.html),
// Duration-Based Session Stickiness (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html#enable-sticky-sessions-duration),
// and Application-Controlled Session Stickiness (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-sticky-sessions.html#enable-sticky-sessions-application)
// in the Classic Load Balancers Guide.
//
// Returns awserr.Error for service API and SDK errors. Use runtime type assertions
// with awserr.Error's Code and Message methods to get detailed information about
// the error.
//
// See the AWS API reference guide for Elastic Load Balancing's
// API operation SetLoadBalancerPoliciesOfListener for usage and error information.
//
// Returned Error Codes:
//   * ErrCodeAccessPointNotFoundException "LoadBalancerNotFound"
//   The specified load balancer does not exist.
//
//   * ErrCodePolicyNotFoundException "PolicyNotFound"
//   One or more of the specified policies do not exist.
//
//   * ErrCodeListenerNotFoundException "ListenerNotFound"
//   The load balancer does not have a listener configured at the specified port.
//
//   * ErrCodeInvalidConfigurationRequestException "InvalidConfigurationRequest"
//   The requested configuration change is not valid.
//
// See also, https://docs.aws.amazon.com/goto/WebAPI/elasticloadbalancing-2012-06-01/SetLoadBalancerPoliciesOfListener
func (c *ELB) SetLoadBalancerPoliciesOfListener(input *SetLoadBalancerPoliciesOfListenerInput) (*SetLoadBalancerPoliciesOfListenerOutput, error) {
	req, out := c.SetLoadBalancerPoliciesOfListenerRequest(input)
	return out, req.Send()
}

// SetLoadBalancerPoliciesOfListenerWithContext is the same as SetLoadBalancerPoliciesOfListener with the addition of
// the ability to pass a context and additional request options.
//
// See SetLoadBalancerPoliciesOfListener for details on how to use this API operation.
//
// The context must be non-nil and will be used for request cancellation. If
// the context is nil a panic will occur. In the future the SDK may create
// sub-contexts for http.Requests. See https://golang.org/pkg/context/
// for more information on using Contexts.
func (c *ELB) SetLoadBalancerPoliciesOfListenerWithContext(ctx aws.Context, input *SetLoadBalancerPoliciesOfListenerInput, opts ...request.Option) (*SetLoadBalancerPoliciesOfListenerOutput, error) {
	req, out := c.SetLoadBalancerPoliciesOfListenerRequest(input)
	req.SetContext(ctx)
	req.ApplyOptions(opts...)
	return out, req.Send()
}

// Information about the AccessLog attribute.
type AccessLog struct {
	_ struct{} `type:"structure"`

	// The interval for publishing the access logs. You can specify an interval
	// of either 5 minutes or 60 minutes.
	//
	// Default: 60 minutes
	EmitInterval *int64 `type:"integer"`

	// Specifies whether access logs are enabled for the load balancer.
	//
	// Enabled is a required field
	Enabled *bool `type:"boolean" required:"true"`

	// The name of the Amazon S3 bucket where the access logs are stored.
	S3BucketName *string `type:"string"`

	// The logical hierarchy you created for your Amazon S3 bucket, for example
	// my-bucket-prefix/prod. If the prefix is not provided, the log is placed at
	// the root level of the bucket.
	S3BucketPrefix *string `type:"string"`
}

// String returns the string representation
func (s AccessLog) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AccessLog) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AccessLog) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AccessLog"}
	if s.Enabled == nil {
		invalidParams.Add(request.NewErrParamRequired("Enabled"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetEmitInterval sets the EmitInterval field's value.
func (s *AccessLog) SetEmitInterval(v int64) *AccessLog {
	s.EmitInterval = &v
	return s
}

// SetEnabled sets the Enabled field's value.
func (s *AccessLog) SetEnabled(v bool) *AccessLog {
	s.Enabled = &v
	return s
}

// SetS3BucketName sets the S3BucketName field's value.
func (s *AccessLog) SetS3BucketName(v string) *AccessLog {
	s.S3BucketName = &v
	return s
}

// SetS3BucketPrefix sets the S3BucketPrefix field's value.
func (s *AccessLog) SetS3BucketPrefix(v string) *AccessLog {
	s.S3BucketPrefix = &v
	return s
}

// Contains the parameters for AddTags.
type AddTagsInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer. You can specify one load balancer only.
	//
	// LoadBalancerNames is a required field
	LoadBalancerNames []*string `type:"list" required:"true"`

	// The tags.
	//
	// Tags is a required field
	Tags []*Tag `min:"1" type:"list" required:"true"`
}

// String returns the string representation
func (s AddTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AddTagsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AddTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AddTagsInput"}
	if s.LoadBalancerNames == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerNames"))
	}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *AddTagsInput) SetLoadBalancerNames(v []*string) *AddTagsInput {
	s.LoadBalancerNames = v
	return s
}

// SetTags sets the Tags field's value.
func (s *AddTagsInput) SetTags(v []*Tag) *AddTagsInput {
	s.Tags = v
	return s
}

// Contains the output of AddTags.
type AddTagsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s AddTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AddTagsOutput) GoString() string {
	return s.String()
}

// This data type is reserved.
type AdditionalAttribute struct {
	_ struct{} `type:"structure"`

	// This parameter is reserved.
	Key *string `type:"string"`

	// This parameter is reserved.
	Value *string `type:"string"`
}

// String returns the string representation
func (s AdditionalAttribute) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AdditionalAttribute) GoString() string {
	return s.String()
}

// SetKey sets the Key field's value.
func (s *AdditionalAttribute) SetKey(v string) *AdditionalAttribute {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *AdditionalAttribute) SetValue(v string) *AdditionalAttribute {
	s.Value = &v
	return s
}

// Information about a policy for application-controlled session stickiness.
type AppCookieStickinessPolicy struct {
	_ struct{} `type:"structure"`

	// The name of the application cookie used for stickiness.
	CookieName *string `type:"string"`

	// The mnemonic name for the policy being created. The name must be unique within
	// a set of policies for this load balancer.
	PolicyName *string `type:"string"`
}

// String returns the string representation
func (s AppCookieStickinessPolicy) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AppCookieStickinessPolicy) GoString() string {
	return s.String()
}

// SetCookieName sets the CookieName field's value.
func (s *AppCookieStickinessPolicy) SetCookieName(v string) *AppCookieStickinessPolicy {
	s.CookieName = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *AppCookieStickinessPolicy) SetPolicyName(v string) *AppCookieStickinessPolicy {
	s.PolicyName = &v
	return s
}

// Contains the parameters for ApplySecurityGroupsToLoadBalancer.
type ApplySecurityGroupsToLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The IDs of the security groups to associate with the load balancer. Note
	// that you cannot specify the name of the security group.
	//
	// SecurityGroups is a required field
	SecurityGroups []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s ApplySecurityGroupsToLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ApplySecurityGroupsToLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ApplySecurityGroupsToLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ApplySecurityGroupsToLoadBalancerInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.SecurityGroups == nil {
		invalidParams.Add(request.NewErrParamRequired("SecurityGroups"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *ApplySecurityGroupsToLoadBalancerInput) SetLoadBalancerName(v string) *ApplySecurityGroupsToLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *ApplySecurityGroupsToLoadBalancerInput) SetSecurityGroups(v []*string) *ApplySecurityGroupsToLoadBalancerInput {
	s.SecurityGroups = v
	return s
}

// Contains the output of ApplySecurityGroupsToLoadBalancer.
type ApplySecurityGroupsToLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The IDs of the security groups associated with the load balancer.
	SecurityGroups []*string `type:"list"`
}

// String returns the string representation
func (s ApplySecurityGroupsToLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ApplySecurityGroupsToLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *ApplySecurityGroupsToLoadBalancerOutput) SetSecurityGroups(v []*string) *ApplySecurityGroupsToLoadBalancerOutput {
	s.SecurityGroups = v
	return s
}

// Contains the parameters for AttachLoaBalancerToSubnets.
type AttachLoadBalancerToSubnetsInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The IDs of the subnets to add. You can add only one subnet per Availability
	// Zone.
	//
	// Subnets is a required field
	Subnets []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s AttachLoadBalancerToSubnetsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancerToSubnetsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *AttachLoadBalancerToSubnetsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "AttachLoadBalancerToSubnetsInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.Subnets == nil {
		invalidParams.Add(request.NewErrParamRequired("Subnets"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *AttachLoadBalancerToSubnetsInput) SetLoadBalancerName(v string) *AttachLoadBalancerToSubnetsInput {
	s.LoadBalancerName = &v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *AttachLoadBalancerToSubnetsInput) SetSubnets(v []*string) *AttachLoadBalancerToSubnetsInput {
	s.Subnets = v
	return s
}

// Contains the output of AttachLoadBalancerToSubnets.
type AttachLoadBalancerToSubnetsOutput struct {
	_ struct{} `type:"structure"`

	// The IDs of the subnets attached to the load balancer.
	Subnets []*string `type:"list"`
}

// String returns the string representation
func (s AttachLoadBalancerToSubnetsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s AttachLoadBalancerToSubnetsOutput) GoString() string {
	return s.String()
}

// SetSubnets sets the Subnets field's value.
func (s *AttachLoadBalancerToSubnetsOutput) SetSubnets(v []*string) *AttachLoadBalancerToSubnetsOutput {
	s.Subnets = v
	return s
}

// Information about the configuration of an EC2 instance.
type BackendServerDescription struct {
	_ struct{} `type:"structure"`

	// The port on which the EC2 instance is listening.
	InstancePort *int64 `min:"1" type:"integer"`

	// The names of the policies enabled for the EC2 instance.
	PolicyNames []*string `type:"list"`
}

// String returns the string representation
func (s BackendServerDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s BackendServerDescription) GoString() string {
	return s.String()
}

// SetInstancePort sets the InstancePort field's value.
func (s *BackendServerDescription) SetInstancePort(v int64) *BackendServerDescription {
	s.InstancePort = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *BackendServerDescription) SetPolicyNames(v []*string) *BackendServerDescription {
	s.PolicyNames = v
	return s
}

// Contains the parameters for ConfigureHealthCheck.
type ConfigureHealthCheckInput struct {
	_ struct{} `type:"structure"`

	// The configuration information.
	//
	// HealthCheck is a required field
	HealthCheck *HealthCheck `type:"structure" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s ConfigureHealthCheckInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ConfigureHealthCheckInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ConfigureHealthCheckInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ConfigureHealthCheckInput"}
	if s.HealthCheck == nil {
		invalidParams.Add(request.NewErrParamRequired("HealthCheck"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.HealthCheck != nil {
		if err := s.HealthCheck.Validate(); err != nil {
			invalidParams.AddNested("HealthCheck", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetHealthCheck sets the HealthCheck field's value.
func (s *ConfigureHealthCheckInput) SetHealthCheck(v *HealthCheck) *ConfigureHealthCheckInput {
	s.HealthCheck = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *ConfigureHealthCheckInput) SetLoadBalancerName(v string) *ConfigureHealthCheckInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of ConfigureHealthCheck.
type ConfigureHealthCheckOutput struct {
	_ struct{} `type:"structure"`

	// The updated health check.
	HealthCheck *HealthCheck `type:"structure"`
}

// String returns the string representation
func (s ConfigureHealthCheckOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ConfigureHealthCheckOutput) GoString() string {
	return s.String()
}

// SetHealthCheck sets the HealthCheck field's value.
func (s *ConfigureHealthCheckOutput) SetHealthCheck(v *HealthCheck) *ConfigureHealthCheckOutput {
	s.HealthCheck = v
	return s
}

// Information about the ConnectionDraining attribute.
type ConnectionDraining struct {
	_ struct{} `type:"structure"`

	// Specifies whether connection draining is enabled for the load balancer.
	//
	// Enabled is a required field
	Enabled *bool `type:"boolean" required:"true"`

	// The maximum time, in seconds, to keep the existing connections open before
	// deregistering the instances.
	Timeout *int64 `type:"integer"`
}

// String returns the string representation
func (s ConnectionDraining) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ConnectionDraining) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ConnectionDraining) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ConnectionDraining"}
	if s.Enabled == nil {
		invalidParams.Add(request.NewErrParamRequired("Enabled"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetEnabled sets the Enabled field's value.
func (s *ConnectionDraining) SetEnabled(v bool) *ConnectionDraining {
	s.Enabled = &v
	return s
}

// SetTimeout sets the Timeout field's value.
func (s *ConnectionDraining) SetTimeout(v int64) *ConnectionDraining {
	s.Timeout = &v
	return s
}

// Information about the ConnectionSettings attribute.
type ConnectionSettings struct {
	_ struct{} `type:"structure"`

	// The time, in seconds, that the connection is allowed to be idle (no data
	// has been sent over the connection) before it is closed by the load balancer.
	//
	// IdleTimeout is a required field
	IdleTimeout *int64 `min:"1" type:"integer" required:"true"`
}

// String returns the string representation
func (s ConnectionSettings) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ConnectionSettings) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ConnectionSettings) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ConnectionSettings"}
	if s.IdleTimeout == nil {
		invalidParams.Add(request.NewErrParamRequired("IdleTimeout"))
	}
	if s.IdleTimeout != nil && *s.IdleTimeout < 1 {
		invalidParams.Add(request.NewErrParamMinValue("IdleTimeout", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetIdleTimeout sets the IdleTimeout field's value.
func (s *ConnectionSettings) SetIdleTimeout(v int64) *ConnectionSettings {
	s.IdleTimeout = &v
	return s
}

// Contains the parameters for CreateAppCookieStickinessPolicy.
type CreateAppCookieStickinessPolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the application cookie used for stickiness.
	//
	// CookieName is a required field
	CookieName *string `type:"string" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The name of the policy being created. Policy names must consist of alphanumeric
	// characters and dashes (-). This name must be unique within the set of policies
	// for this load balancer.
	//
	// PolicyName is a required field
	PolicyName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s CreateAppCookieStickinessPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateAppCookieStickinessPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateAppCookieStickinessPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateAppCookieStickinessPolicyInput"}
	if s.CookieName == nil {
		invalidParams.Add(request.NewErrParamRequired("CookieName"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetCookieName sets the CookieName field's value.
func (s *CreateAppCookieStickinessPolicyInput) SetCookieName(v string) *CreateAppCookieStickinessPolicyInput {
	s.CookieName = &v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *CreateAppCookieStickinessPolicyInput) SetLoadBalancerName(v string) *CreateAppCookieStickinessPolicyInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *CreateAppCookieStickinessPolicyInput) SetPolicyName(v string) *CreateAppCookieStickinessPolicyInput {
	s.PolicyName = &v
	return s
}

// Contains the output for CreateAppCookieStickinessPolicy.
type CreateAppCookieStickinessPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateAppCookieStickinessPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateAppCookieStickinessPolicyOutput) GoString() string {
	return s.String()
}

// Contains the parameters for CreateLBCookieStickinessPolicy.
type CreateLBCookieStickinessPolicyInput struct {
	_ struct{} `type:"structure"`

	// The time period, in seconds, after which the cookie should be considered
	// stale. If you do not specify this parameter, the default value is 0, which
	// indicates that the sticky session should last for the duration of the browser
	// session.
	CookieExpirationPeriod *int64 `type:"long"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The name of the policy being created. Policy names must consist of alphanumeric
	// characters and dashes (-). This name must be unique within the set of policies
	// for this load balancer.
	//
	// PolicyName is a required field
	PolicyName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s CreateLBCookieStickinessPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLBCookieStickinessPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLBCookieStickinessPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLBCookieStickinessPolicyInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetCookieExpirationPeriod sets the CookieExpirationPeriod field's value.
func (s *CreateLBCookieStickinessPolicyInput) SetCookieExpirationPeriod(v int64) *CreateLBCookieStickinessPolicyInput {
	s.CookieExpirationPeriod = &v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *CreateLBCookieStickinessPolicyInput) SetLoadBalancerName(v string) *CreateLBCookieStickinessPolicyInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *CreateLBCookieStickinessPolicyInput) SetPolicyName(v string) *CreateLBCookieStickinessPolicyInput {
	s.PolicyName = &v
	return s
}

// Contains the output for CreateLBCookieStickinessPolicy.
type CreateLBCookieStickinessPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLBCookieStickinessPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLBCookieStickinessPolicyOutput) GoString() string {
	return s.String()
}

// Contains the parameters for CreateLoadBalancer.
type CreateLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// One or more Availability Zones from the same region as the load balancer.
	//
	// You must specify at least one Availability Zone.
	//
	// You can add more Availability Zones after you create the load balancer using
	// EnableAvailabilityZonesForLoadBalancer.
	AvailabilityZones []*string `type:"list"`

	// The listeners.
	//
	// For more information, see Listeners for Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html)
	// in the Classic Load Balancers Guide.
	//
	// Listeners is a required field
	Listeners []*Listener `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// This name must be unique within your set of load balancers for the region,
	// must have a maximum of 32 characters, must contain only alphanumeric characters
	// or hyphens, and cannot begin or end with a hyphen.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The type of a load balancer. Valid only for load balancers in a VPC.
	//
	// By default, Elastic Load Balancing creates an Internet-facing load balancer
	// with a DNS name that resolves to public IP addresses. For more information
	// about Internet-facing and Internal load balancers, see Load Balancer Scheme
	// (http://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/how-elastic-load-balancing-works.html#load-balancer-scheme)
	// in the Elastic Load Balancing User Guide.
	//
	// Specify internal to create a load balancer with a DNS name that resolves
	// to private IP addresses.
	Scheme *string `type:"string"`

	// The IDs of the security groups to assign to the load balancer.
	SecurityGroups []*string `type:"list"`

	// The IDs of the subnets in your VPC to attach to the load balancer. Specify
	// one subnet per Availability Zone specified in AvailabilityZones.
	Subnets []*string `type:"list"`

	// A list of tags to assign to the load balancer.
	//
	// For more information about tagging your load balancer, see Tag Your Classic
	// Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/add-remove-tags.html)
	// in the Classic Load Balancers Guide.
	Tags []*Tag `min:"1" type:"list"`
}

// String returns the string representation
func (s CreateLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerInput"}
	if s.Listeners == nil {
		invalidParams.Add(request.NewErrParamRequired("Listeners"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}
	if s.Listeners != nil {
		for i, v := range s.Listeners {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Listeners", i), err.(request.ErrInvalidParams))
			}
		}
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *CreateLoadBalancerInput) SetAvailabilityZones(v []*string) *CreateLoadBalancerInput {
	s.AvailabilityZones = v
	return s
}

// SetListeners sets the Listeners field's value.
func (s *CreateLoadBalancerInput) SetListeners(v []*Listener) *CreateLoadBalancerInput {
	s.Listeners = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *CreateLoadBalancerInput) SetLoadBalancerName(v string) *CreateLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// SetScheme sets the Scheme field's value.
func (s *CreateLoadBalancerInput) SetScheme(v string) *CreateLoadBalancerInput {
	s.Scheme = &v
	return s
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *CreateLoadBalancerInput) SetSecurityGroups(v []*string) *CreateLoadBalancerInput {
	s.SecurityGroups = v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *CreateLoadBalancerInput) SetSubnets(v []*string) *CreateLoadBalancerInput {
	s.Subnets = v
	return s
}

// SetTags sets the Tags field's value.
func (s *CreateLoadBalancerInput) SetTags(v []*Tag) *CreateLoadBalancerInput {
	s.Tags = v
	return s
}

// Contains the parameters for CreateLoadBalancerListeners.
type CreateLoadBalancerListenersInput struct {
	_ struct{} `type:"structure"`

	// The listeners.
	//
	// Listeners is a required field
	Listeners []*Listener `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s CreateLoadBalancerListenersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerListenersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLoadBalancerListenersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerListenersInput"}
	if s.Listeners == nil {
		invalidParams.Add(request.NewErrParamRequired("Listeners"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.Listeners != nil {
		for i, v := range s.Listeners {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Listeners", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetListeners sets the Listeners field's value.
func (s *CreateLoadBalancerListenersInput) SetListeners(v []*Listener) *CreateLoadBalancerListenersInput {
	s.Listeners = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *CreateLoadBalancerListenersInput) SetLoadBalancerName(v string) *CreateLoadBalancerListenersInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the parameters for CreateLoadBalancerListener.
type CreateLoadBalancerListenersOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLoadBalancerListenersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerListenersOutput) GoString() string {
	return s.String()
}

// Contains the output for CreateLoadBalancer.
type CreateLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The DNS name of the load balancer.
	DNSName *string `type:"string"`
}

// String returns the string representation
func (s CreateLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetDNSName sets the DNSName field's value.
func (s *CreateLoadBalancerOutput) SetDNSName(v string) *CreateLoadBalancerOutput {
	s.DNSName = &v
	return s
}

// Contains the parameters for CreateLoadBalancerPolicy.
type CreateLoadBalancerPolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The policy attributes.
	PolicyAttributes []*PolicyAttribute `type:"list"`

	// The name of the load balancer policy to be created. This name must be unique
	// within the set of policies for this load balancer.
	//
	// PolicyName is a required field
	PolicyName *string `type:"string" required:"true"`

	// The name of the base policy type. To get the list of policy types, use DescribeLoadBalancerPolicyTypes.
	//
	// PolicyTypeName is a required field
	PolicyTypeName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s CreateLoadBalancerPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CreateLoadBalancerPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CreateLoadBalancerPolicyInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}
	if s.PolicyTypeName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyTypeName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *CreateLoadBalancerPolicyInput) SetLoadBalancerName(v string) *CreateLoadBalancerPolicyInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyAttributes sets the PolicyAttributes field's value.
func (s *CreateLoadBalancerPolicyInput) SetPolicyAttributes(v []*PolicyAttribute) *CreateLoadBalancerPolicyInput {
	s.PolicyAttributes = v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *CreateLoadBalancerPolicyInput) SetPolicyName(v string) *CreateLoadBalancerPolicyInput {
	s.PolicyName = &v
	return s
}

// SetPolicyTypeName sets the PolicyTypeName field's value.
func (s *CreateLoadBalancerPolicyInput) SetPolicyTypeName(v string) *CreateLoadBalancerPolicyInput {
	s.PolicyTypeName = &v
	return s
}

// Contains the output of CreateLoadBalancerPolicy.
type CreateLoadBalancerPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s CreateLoadBalancerPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CreateLoadBalancerPolicyOutput) GoString() string {
	return s.String()
}

// Information about the CrossZoneLoadBalancing attribute.
type CrossZoneLoadBalancing struct {
	_ struct{} `type:"structure"`

	// Specifies whether cross-zone load balancing is enabled for the load balancer.
	//
	// Enabled is a required field
	Enabled *bool `type:"boolean" required:"true"`
}

// String returns the string representation
func (s CrossZoneLoadBalancing) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s CrossZoneLoadBalancing) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *CrossZoneLoadBalancing) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "CrossZoneLoadBalancing"}
	if s.Enabled == nil {
		invalidParams.Add(request.NewErrParamRequired("Enabled"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetEnabled sets the Enabled field's value.
func (s *CrossZoneLoadBalancing) SetEnabled(v bool) *CrossZoneLoadBalancing {
	s.Enabled = &v
	return s
}

// Contains the parameters for DeleteLoadBalancer.
type DeleteLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DeleteLoadBalancerInput) SetLoadBalancerName(v string) *DeleteLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the parameters for DeleteLoadBalancerListeners.
type DeleteLoadBalancerListenersInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The client port numbers of the listeners.
	//
	// LoadBalancerPorts is a required field
	LoadBalancerPorts []*int64 `type:"list" required:"true"`
}

// String returns the string representation
func (s DeleteLoadBalancerListenersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerListenersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLoadBalancerListenersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerListenersInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.LoadBalancerPorts == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerPorts"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DeleteLoadBalancerListenersInput) SetLoadBalancerName(v string) *DeleteLoadBalancerListenersInput {
	s.LoadBalancerName = &v
	return s
}

// SetLoadBalancerPorts sets the LoadBalancerPorts field's value.
func (s *DeleteLoadBalancerListenersInput) SetLoadBalancerPorts(v []*int64) *DeleteLoadBalancerListenersInput {
	s.LoadBalancerPorts = v
	return s
}

// Contains the output of DeleteLoadBalancerListeners.
type DeleteLoadBalancerListenersOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLoadBalancerListenersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerListenersOutput) GoString() string {
	return s.String()
}

// Contains the output of DeleteLoadBalancer.
type DeleteLoadBalancerOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerOutput) GoString() string {
	return s.String()
}

// Contains the parameters for DeleteLoadBalancerPolicy.
type DeleteLoadBalancerPolicyInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The name of the policy.
	//
	// PolicyName is a required field
	PolicyName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DeleteLoadBalancerPolicyInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerPolicyInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeleteLoadBalancerPolicyInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeleteLoadBalancerPolicyInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.PolicyName == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DeleteLoadBalancerPolicyInput) SetLoadBalancerName(v string) *DeleteLoadBalancerPolicyInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *DeleteLoadBalancerPolicyInput) SetPolicyName(v string) *DeleteLoadBalancerPolicyInput {
	s.PolicyName = &v
	return s
}

// Contains the output of DeleteLoadBalancerPolicy.
type DeleteLoadBalancerPolicyOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s DeleteLoadBalancerPolicyOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeleteLoadBalancerPolicyOutput) GoString() string {
	return s.String()
}

// Contains the parameters for DeregisterInstancesFromLoadBalancer.
type DeregisterInstancesFromLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The IDs of the instances.
	//
	// Instances is a required field
	Instances []*Instance `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DeregisterInstancesFromLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeregisterInstancesFromLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DeregisterInstancesFromLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DeregisterInstancesFromLoadBalancerInput"}
	if s.Instances == nil {
		invalidParams.Add(request.NewErrParamRequired("Instances"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstances sets the Instances field's value.
func (s *DeregisterInstancesFromLoadBalancerInput) SetInstances(v []*Instance) *DeregisterInstancesFromLoadBalancerInput {
	s.Instances = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DeregisterInstancesFromLoadBalancerInput) SetLoadBalancerName(v string) *DeregisterInstancesFromLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of DeregisterInstancesFromLoadBalancer.
type DeregisterInstancesFromLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The remaining instances registered with the load balancer.
	Instances []*Instance `type:"list"`
}

// String returns the string representation
func (s DeregisterInstancesFromLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DeregisterInstancesFromLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetInstances sets the Instances field's value.
func (s *DeregisterInstancesFromLoadBalancerOutput) SetInstances(v []*Instance) *DeregisterInstancesFromLoadBalancerOutput {
	s.Instances = v
	return s
}

type DescribeAccountLimitsInput struct {
	_ struct{} `type:"structure"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call.
	PageSize *int64 `min:"1" type:"integer"`
}

// String returns the string representation
func (s DescribeAccountLimitsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAccountLimitsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeAccountLimitsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeAccountLimitsInput"}
	if s.PageSize != nil && *s.PageSize < 1 {
		invalidParams.Add(request.NewErrParamMinValue("PageSize", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetMarker sets the Marker field's value.
func (s *DescribeAccountLimitsInput) SetMarker(v string) *DescribeAccountLimitsInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeAccountLimitsInput) SetPageSize(v int64) *DescribeAccountLimitsInput {
	s.PageSize = &v
	return s
}

type DescribeAccountLimitsOutput struct {
	_ struct{} `type:"structure"`

	// Information about the limits.
	Limits []*Limit `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`
}

// String returns the string representation
func (s DescribeAccountLimitsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeAccountLimitsOutput) GoString() string {
	return s.String()
}

// SetLimits sets the Limits field's value.
func (s *DescribeAccountLimitsOutput) SetLimits(v []*Limit) *DescribeAccountLimitsOutput {
	s.Limits = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeAccountLimitsOutput) SetNextMarker(v string) *DescribeAccountLimitsOutput {
	s.NextMarker = &v
	return s
}

// Contains the parameters for DescribeInstanceHealth.
type DescribeInstanceHealthInput struct {
	_ struct{} `type:"structure"`

	// The IDs of the instances.
	Instances []*Instance `type:"list"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DescribeInstanceHealthInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeInstanceHealthInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeInstanceHealthInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeInstanceHealthInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstances sets the Instances field's value.
func (s *DescribeInstanceHealthInput) SetInstances(v []*Instance) *DescribeInstanceHealthInput {
	s.Instances = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DescribeInstanceHealthInput) SetLoadBalancerName(v string) *DescribeInstanceHealthInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output for DescribeInstanceHealth.
type DescribeInstanceHealthOutput struct {
	_ struct{} `type:"structure"`

	// Information about the health of the instances.
	InstanceStates []*InstanceState `type:"list"`
}

// String returns the string representation
func (s DescribeInstanceHealthOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeInstanceHealthOutput) GoString() string {
	return s.String()
}

// SetInstanceStates sets the InstanceStates field's value.
func (s *DescribeInstanceHealthOutput) SetInstanceStates(v []*InstanceState) *DescribeInstanceHealthOutput {
	s.InstanceStates = v
	return s
}

// Contains the parameters for DescribeLoadBalancerAttributes.
type DescribeLoadBalancerAttributesInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DescribeLoadBalancerAttributesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerAttributesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLoadBalancerAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLoadBalancerAttributesInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DescribeLoadBalancerAttributesInput) SetLoadBalancerName(v string) *DescribeLoadBalancerAttributesInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of DescribeLoadBalancerAttributes.
type DescribeLoadBalancerAttributesOutput struct {
	_ struct{} `type:"structure"`

	// Information about the load balancer attributes.
	LoadBalancerAttributes *LoadBalancerAttributes `type:"structure"`
}

// String returns the string representation
func (s DescribeLoadBalancerAttributesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerAttributesOutput) GoString() string {
	return s.String()
}

// SetLoadBalancerAttributes sets the LoadBalancerAttributes field's value.
func (s *DescribeLoadBalancerAttributesOutput) SetLoadBalancerAttributes(v *LoadBalancerAttributes) *DescribeLoadBalancerAttributesOutput {
	s.LoadBalancerAttributes = v
	return s
}

// Contains the parameters for DescribeLoadBalancerPolicies.
type DescribeLoadBalancerPoliciesInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	LoadBalancerName *string `type:"string"`

	// The names of the policies.
	PolicyNames []*string `type:"list"`
}

// String returns the string representation
func (s DescribeLoadBalancerPoliciesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerPoliciesInput) GoString() string {
	return s.String()
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DescribeLoadBalancerPoliciesInput) SetLoadBalancerName(v string) *DescribeLoadBalancerPoliciesInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *DescribeLoadBalancerPoliciesInput) SetPolicyNames(v []*string) *DescribeLoadBalancerPoliciesInput {
	s.PolicyNames = v
	return s
}

// Contains the output of DescribeLoadBalancerPolicies.
type DescribeLoadBalancerPoliciesOutput struct {
	_ struct{} `type:"structure"`

	// Information about the policies.
	PolicyDescriptions []*PolicyDescription `type:"list"`
}

// String returns the string representation
func (s DescribeLoadBalancerPoliciesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerPoliciesOutput) GoString() string {
	return s.String()
}

// SetPolicyDescriptions sets the PolicyDescriptions field's value.
func (s *DescribeLoadBalancerPoliciesOutput) SetPolicyDescriptions(v []*PolicyDescription) *DescribeLoadBalancerPoliciesOutput {
	s.PolicyDescriptions = v
	return s
}

// Contains the parameters for DescribeLoadBalancerPolicyTypes.
type DescribeLoadBalancerPolicyTypesInput struct {
	_ struct{} `type:"structure"`

	// The names of the policy types. If no names are specified, describes all policy
	// types defined by Elastic Load Balancing.
	PolicyTypeNames []*string `type:"list"`
}

// String returns the string representation
func (s DescribeLoadBalancerPolicyTypesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerPolicyTypesInput) GoString() string {
	return s.String()
}

// SetPolicyTypeNames sets the PolicyTypeNames field's value.
func (s *DescribeLoadBalancerPolicyTypesInput) SetPolicyTypeNames(v []*string) *DescribeLoadBalancerPolicyTypesInput {
	s.PolicyTypeNames = v
	return s
}

// Contains the output of DescribeLoadBalancerPolicyTypes.
type DescribeLoadBalancerPolicyTypesOutput struct {
	_ struct{} `type:"structure"`

	// Information about the policy types.
	PolicyTypeDescriptions []*PolicyTypeDescription `type:"list"`
}

// String returns the string representation
func (s DescribeLoadBalancerPolicyTypesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancerPolicyTypesOutput) GoString() string {
	return s.String()
}

// SetPolicyTypeDescriptions sets the PolicyTypeDescriptions field's value.
func (s *DescribeLoadBalancerPolicyTypesOutput) SetPolicyTypeDescriptions(v []*PolicyTypeDescription) *DescribeLoadBalancerPolicyTypesOutput {
	s.PolicyTypeDescriptions = v
	return s
}

// Contains the parameters for DescribeLoadBalancers.
type DescribeLoadBalancersInput struct {
	_ struct{} `type:"structure"`

	// The names of the load balancers.
	LoadBalancerNames []*string `type:"list"`

	// The marker for the next set of results. (You received this marker from a
	// previous call.)
	Marker *string `type:"string"`

	// The maximum number of results to return with this call (a number from 1 to
	// 400). The default is 400.
	PageSize *int64 `min:"1" type:"integer"`
}

// String returns the string representation
func (s DescribeLoadBalancersInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancersInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeLoadBalancersInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeLoadBalancersInput"}
	if s.PageSize != nil && *s.PageSize < 1 {
		invalidParams.Add(request.NewErrParamMinValue("PageSize", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *DescribeLoadBalancersInput) SetLoadBalancerNames(v []*string) *DescribeLoadBalancersInput {
	s.LoadBalancerNames = v
	return s
}

// SetMarker sets the Marker field's value.
func (s *DescribeLoadBalancersInput) SetMarker(v string) *DescribeLoadBalancersInput {
	s.Marker = &v
	return s
}

// SetPageSize sets the PageSize field's value.
func (s *DescribeLoadBalancersInput) SetPageSize(v int64) *DescribeLoadBalancersInput {
	s.PageSize = &v
	return s
}

// Contains the parameters for DescribeLoadBalancers.
type DescribeLoadBalancersOutput struct {
	_ struct{} `type:"structure"`

	// Information about the load balancers.
	LoadBalancerDescriptions []*LoadBalancerDescription `type:"list"`

	// The marker to use when requesting the next set of results. If there are no
	// additional results, the string is empty.
	NextMarker *string `type:"string"`
}

// String returns the string representation
func (s DescribeLoadBalancersOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeLoadBalancersOutput) GoString() string {
	return s.String()
}

// SetLoadBalancerDescriptions sets the LoadBalancerDescriptions field's value.
func (s *DescribeLoadBalancersOutput) SetLoadBalancerDescriptions(v []*LoadBalancerDescription) *DescribeLoadBalancersOutput {
	s.LoadBalancerDescriptions = v
	return s
}

// SetNextMarker sets the NextMarker field's value.
func (s *DescribeLoadBalancersOutput) SetNextMarker(v string) *DescribeLoadBalancersOutput {
	s.NextMarker = &v
	return s
}

// Contains the parameters for DescribeTags.
type DescribeTagsInput struct {
	_ struct{} `type:"structure"`

	// The names of the load balancers.
	//
	// LoadBalancerNames is a required field
	LoadBalancerNames []*string `min:"1" type:"list" required:"true"`
}

// String returns the string representation
func (s DescribeTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTagsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DescribeTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DescribeTagsInput"}
	if s.LoadBalancerNames == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerNames"))
	}
	if s.LoadBalancerNames != nil && len(s.LoadBalancerNames) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("LoadBalancerNames", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *DescribeTagsInput) SetLoadBalancerNames(v []*string) *DescribeTagsInput {
	s.LoadBalancerNames = v
	return s
}

// Contains the output for DescribeTags.
type DescribeTagsOutput struct {
	_ struct{} `type:"structure"`

	// Information about the tags.
	TagDescriptions []*TagDescription `type:"list"`
}

// String returns the string representation
func (s DescribeTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DescribeTagsOutput) GoString() string {
	return s.String()
}

// SetTagDescriptions sets the TagDescriptions field's value.
func (s *DescribeTagsOutput) SetTagDescriptions(v []*TagDescription) *DescribeTagsOutput {
	s.TagDescriptions = v
	return s
}

// Contains the parameters for DetachLoadBalancerFromSubnets.
type DetachLoadBalancerFromSubnetsInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The IDs of the subnets.
	//
	// Subnets is a required field
	Subnets []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s DetachLoadBalancerFromSubnetsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancerFromSubnetsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DetachLoadBalancerFromSubnetsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DetachLoadBalancerFromSubnetsInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.Subnets == nil {
		invalidParams.Add(request.NewErrParamRequired("Subnets"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DetachLoadBalancerFromSubnetsInput) SetLoadBalancerName(v string) *DetachLoadBalancerFromSubnetsInput {
	s.LoadBalancerName = &v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *DetachLoadBalancerFromSubnetsInput) SetSubnets(v []*string) *DetachLoadBalancerFromSubnetsInput {
	s.Subnets = v
	return s
}

// Contains the output of DetachLoadBalancerFromSubnets.
type DetachLoadBalancerFromSubnetsOutput struct {
	_ struct{} `type:"structure"`

	// The IDs of the remaining subnets for the load balancer.
	Subnets []*string `type:"list"`
}

// String returns the string representation
func (s DetachLoadBalancerFromSubnetsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DetachLoadBalancerFromSubnetsOutput) GoString() string {
	return s.String()
}

// SetSubnets sets the Subnets field's value.
func (s *DetachLoadBalancerFromSubnetsOutput) SetSubnets(v []*string) *DetachLoadBalancerFromSubnetsOutput {
	s.Subnets = v
	return s
}

// Contains the parameters for DisableAvailabilityZonesForLoadBalancer.
type DisableAvailabilityZonesForLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The Availability Zones.
	//
	// AvailabilityZones is a required field
	AvailabilityZones []*string `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s DisableAvailabilityZonesForLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DisableAvailabilityZonesForLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *DisableAvailabilityZonesForLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "DisableAvailabilityZonesForLoadBalancerInput"}
	if s.AvailabilityZones == nil {
		invalidParams.Add(request.NewErrParamRequired("AvailabilityZones"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *DisableAvailabilityZonesForLoadBalancerInput) SetAvailabilityZones(v []*string) *DisableAvailabilityZonesForLoadBalancerInput {
	s.AvailabilityZones = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *DisableAvailabilityZonesForLoadBalancerInput) SetLoadBalancerName(v string) *DisableAvailabilityZonesForLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output for DisableAvailabilityZonesForLoadBalancer.
type DisableAvailabilityZonesForLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The remaining Availability Zones for the load balancer.
	AvailabilityZones []*string `type:"list"`
}

// String returns the string representation
func (s DisableAvailabilityZonesForLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s DisableAvailabilityZonesForLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *DisableAvailabilityZonesForLoadBalancerOutput) SetAvailabilityZones(v []*string) *DisableAvailabilityZonesForLoadBalancerOutput {
	s.AvailabilityZones = v
	return s
}

// Contains the parameters for EnableAvailabilityZonesForLoadBalancer.
type EnableAvailabilityZonesForLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The Availability Zones. These must be in the same region as the load balancer.
	//
	// AvailabilityZones is a required field
	AvailabilityZones []*string `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s EnableAvailabilityZonesForLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnableAvailabilityZonesForLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *EnableAvailabilityZonesForLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "EnableAvailabilityZonesForLoadBalancerInput"}
	if s.AvailabilityZones == nil {
		invalidParams.Add(request.NewErrParamRequired("AvailabilityZones"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *EnableAvailabilityZonesForLoadBalancerInput) SetAvailabilityZones(v []*string) *EnableAvailabilityZonesForLoadBalancerInput {
	s.AvailabilityZones = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *EnableAvailabilityZonesForLoadBalancerInput) SetLoadBalancerName(v string) *EnableAvailabilityZonesForLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of EnableAvailabilityZonesForLoadBalancer.
type EnableAvailabilityZonesForLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The updated list of Availability Zones for the load balancer.
	AvailabilityZones []*string `type:"list"`
}

// String returns the string representation
func (s EnableAvailabilityZonesForLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s EnableAvailabilityZonesForLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *EnableAvailabilityZonesForLoadBalancerOutput) SetAvailabilityZones(v []*string) *EnableAvailabilityZonesForLoadBalancerOutput {
	s.AvailabilityZones = v
	return s
}

// Information about a health check.
type HealthCheck struct {
	_ struct{} `type:"structure"`

	// The number of consecutive health checks successes required before moving
	// the instance to the Healthy state.
	//
	// HealthyThreshold is a required field
	HealthyThreshold *int64 `min:"2" type:"integer" required:"true"`

	// The approximate interval, in seconds, between health checks of an individual
	// instance.
	//
	// Interval is a required field
	Interval *int64 `min:"5" type:"integer" required:"true"`

	// The instance being checked. The protocol is either TCP, HTTP, HTTPS, or SSL.
	// The range of valid ports is one (1) through 65535.
	//
	// TCP is the default, specified as a TCP: port pair, for example "TCP:5000".
	// In this case, a health check simply attempts to open a TCP connection to
	// the instance on the specified port. Failure to connect within the configured
	// timeout is considered unhealthy.
	//
	// SSL is also specified as SSL: port pair, for example, SSL:5000.
	//
	// For HTTP/HTTPS, you must include a ping path in the string. HTTP is specified
	// as a HTTP:port;/;PathToPing; grouping, for example "HTTP:80/weather/us/wa/seattle".
	// In this case, a HTTP GET request is issued to the instance on the given port
	// and path. Any answer other than "200 OK" within the timeout period is considered
	// unhealthy.
	//
	// The total length of the HTTP ping target must be 1024 16-bit Unicode characters
	// or less.
	//
	// Target is a required field
	Target *string `type:"string" required:"true"`

	// The amount of time, in seconds, during which no response means a failed health
	// check.
	//
	// This value must be less than the Interval value.
	//
	// Timeout is a required field
	Timeout *int64 `min:"2" type:"integer" required:"true"`

	// The number of consecutive health check failures required before moving the
	// instance to the Unhealthy state.
	//
	// UnhealthyThreshold is a required field
	UnhealthyThreshold *int64 `min:"2" type:"integer" required:"true"`
}

// String returns the string representation
func (s HealthCheck) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s HealthCheck) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *HealthCheck) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "HealthCheck"}
	if s.HealthyThreshold == nil {
		invalidParams.Add(request.NewErrParamRequired("HealthyThreshold"))
	}
	if s.HealthyThreshold != nil && *s.HealthyThreshold < 2 {
		invalidParams.Add(request.NewErrParamMinValue("HealthyThreshold", 2))
	}
	if s.Interval == nil {
		invalidParams.Add(request.NewErrParamRequired("Interval"))
	}
	if s.Interval != nil && *s.Interval < 5 {
		invalidParams.Add(request.NewErrParamMinValue("Interval", 5))
	}
	if s.Target == nil {
		invalidParams.Add(request.NewErrParamRequired("Target"))
	}
	if s.Timeout == nil {
		invalidParams.Add(request.NewErrParamRequired("Timeout"))
	}
	if s.Timeout != nil && *s.Timeout < 2 {
		invalidParams.Add(request.NewErrParamMinValue("Timeout", 2))
	}
	if s.UnhealthyThreshold == nil {
		invalidParams.Add(request.NewErrParamRequired("UnhealthyThreshold"))
	}
	if s.UnhealthyThreshold != nil && *s.UnhealthyThreshold < 2 {
		invalidParams.Add(request.NewErrParamMinValue("UnhealthyThreshold", 2))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetHealthyThreshold sets the HealthyThreshold field's value.
func (s *HealthCheck) SetHealthyThreshold(v int64) *HealthCheck {
	s.HealthyThreshold = &v
	return s
}

// SetInterval sets the Interval field's value.
func (s *HealthCheck) SetInterval(v int64) *HealthCheck {
	s.Interval = &v
	return s
}

// SetTarget sets the Target field's value.
func (s *HealthCheck) SetTarget(v string) *HealthCheck {
	s.Target = &v
	return s
}

// SetTimeout sets the Timeout field's value.
func (s *HealthCheck) SetTimeout(v int64) *HealthCheck {
	s.Timeout = &v
	return s
}

// SetUnhealthyThreshold sets the UnhealthyThreshold field's value.
func (s *HealthCheck) SetUnhealthyThreshold(v int64) *HealthCheck {
	s.UnhealthyThreshold = &v
	return s
}

// The ID of an EC2 instance.
type Instance struct {
	_ struct{} `type:"structure"`

	// The instance ID.
	InstanceId *string `type:"string"`
}

// String returns the string representation
func (s Instance) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Instance) GoString() string {
	return s.String()
}

// SetInstanceId sets the InstanceId field's value.
func (s *Instance) SetInstanceId(v string) *Instance {
	s.InstanceId = &v
	return s
}

// Information about the state of an EC2 instance.
type InstanceState struct {
	_ struct{} `type:"structure"`

	// A description of the instance state. This string can contain one or more
	// of the following messages.
	//
	//    * N/A
	//
	//    * A transient error occurred. Please try again later.
	//
	//    * Instance has failed at least the UnhealthyThreshold number of health
	//    checks consecutively.
	//
	//    * Instance has not passed the configured HealthyThreshold number of health
	//    checks consecutively.
	//
	//    * Instance registration is still in progress.
	//
	//    * Instance is in the EC2 Availability Zone for which LoadBalancer is not
	//    configured to route traffic to.
	//
	//    * Instance is not currently registered with the LoadBalancer.
	//
	//    * Instance deregistration currently in progress.
	//
	//    * Disable Availability Zone is currently in progress.
	//
	//    * Instance is in pending state.
	//
	//    * Instance is in stopped state.
	//
	//    * Instance is in terminated state.
	Description *string `type:"string"`

	// The ID of the instance.
	InstanceId *string `type:"string"`

	// Information about the cause of OutOfService instances. Specifically, whether
	// the cause is Elastic Load Balancing or the instance.
	//
	// Valid values: ELB | Instance | N/A
	ReasonCode *string `type:"string"`

	// The current state of the instance.
	//
	// Valid values: InService | OutOfService | Unknown
	State *string `type:"string"`
}

// String returns the string representation
func (s InstanceState) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s InstanceState) GoString() string {
	return s.String()
}

// SetDescription sets the Description field's value.
func (s *InstanceState) SetDescription(v string) *InstanceState {
	s.Description = &v
	return s
}

// SetInstanceId sets the InstanceId field's value.
func (s *InstanceState) SetInstanceId(v string) *InstanceState {
	s.InstanceId = &v
	return s
}

// SetReasonCode sets the ReasonCode field's value.
func (s *InstanceState) SetReasonCode(v string) *InstanceState {
	s.ReasonCode = &v
	return s
}

// SetState sets the State field's value.
func (s *InstanceState) SetState(v string) *InstanceState {
	s.State = &v
	return s
}

// Information about a policy for duration-based session stickiness.
type LBCookieStickinessPolicy struct {
	_ struct{} `type:"structure"`

	// The time period, in seconds, after which the cookie should be considered
	// stale. If this parameter is not specified, the stickiness session lasts for
	// the duration of the browser session.
	CookieExpirationPeriod *int64 `type:"long"`

	// The name of the policy. This name must be unique within the set of policies
	// for this load balancer.
	PolicyName *string `type:"string"`
}

// String returns the string representation
func (s LBCookieStickinessPolicy) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LBCookieStickinessPolicy) GoString() string {
	return s.String()
}

// SetCookieExpirationPeriod sets the CookieExpirationPeriod field's value.
func (s *LBCookieStickinessPolicy) SetCookieExpirationPeriod(v int64) *LBCookieStickinessPolicy {
	s.CookieExpirationPeriod = &v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *LBCookieStickinessPolicy) SetPolicyName(v string) *LBCookieStickinessPolicy {
	s.PolicyName = &v
	return s
}

// Information about an Elastic Load Balancing resource limit for your AWS account.
type Limit struct {
	_ struct{} `type:"structure"`

	// The maximum value of the limit.
	Max *string `type:"string"`

	// The name of the limit. The possible values are:
	//
	//    * classic-listeners
	//
	//    * classic-load-balancers
	//
	//    * classic-registered-instances
	Name *string `type:"string"`
}

// String returns the string representation
func (s Limit) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Limit) GoString() string {
	return s.String()
}

// SetMax sets the Max field's value.
func (s *Limit) SetMax(v string) *Limit {
	s.Max = &v
	return s
}

// SetName sets the Name field's value.
func (s *Limit) SetName(v string) *Limit {
	s.Name = &v
	return s
}

// Information about a listener.
//
// For information about the protocols and the ports supported by Elastic Load
// Balancing, see Listeners for Your Classic Load Balancer (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/elb-listener-config.html)
// in the Classic Load Balancers Guide.
type Listener struct {
	_ struct{} `type:"structure"`

	// The port on which the instance is listening.
	//
	// InstancePort is a required field
	InstancePort *int64 `min:"1" type:"integer" required:"true"`

	// The protocol to use for routing traffic to instances: HTTP, HTTPS, TCP, or
	// SSL.
	//
	// If the front-end protocol is HTTP, HTTPS, TCP, or SSL, InstanceProtocol must
	// be at the same protocol.
	//
	// If there is another listener with the same InstancePort whose InstanceProtocol
	// is secure, (HTTPS or SSL), the listener's InstanceProtocol must also be secure.
	//
	// If there is another listener with the same InstancePort whose InstanceProtocol
	// is HTTP or TCP, the listener's InstanceProtocol must be HTTP or TCP.
	InstanceProtocol *string `type:"string"`

	// The port on which the load balancer is listening. On EC2-VPC, you can specify
	// any port from the range 1-65535. On EC2-Classic, you can specify any port
	// from the following list: 25, 80, 443, 465, 587, 1024-65535.
	//
	// LoadBalancerPort is a required field
	LoadBalancerPort *int64 `type:"integer" required:"true"`

	// The load balancer transport protocol to use for routing: HTTP, HTTPS, TCP,
	// or SSL.
	//
	// Protocol is a required field
	Protocol *string `type:"string" required:"true"`

	// The Amazon Resource Name (ARN) of the server certificate.
	SSLCertificateId *string `type:"string"`
}

// String returns the string representation
func (s Listener) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Listener) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *Listener) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Listener"}
	if s.InstancePort == nil {
		invalidParams.Add(request.NewErrParamRequired("InstancePort"))
	}
	if s.InstancePort != nil && *s.InstancePort < 1 {
		invalidParams.Add(request.NewErrParamMinValue("InstancePort", 1))
	}
	if s.LoadBalancerPort == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerPort"))
	}
	if s.Protocol == nil {
		invalidParams.Add(request.NewErrParamRequired("Protocol"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstancePort sets the InstancePort field's value.
func (s *Listener) SetInstancePort(v int64) *Listener {
	s.InstancePort = &v
	return s
}

// SetInstanceProtocol sets the InstanceProtocol field's value.
func (s *Listener) SetInstanceProtocol(v string) *Listener {
	s.InstanceProtocol = &v
	return s
}

// SetLoadBalancerPort sets the LoadBalancerPort field's value.
func (s *Listener) SetLoadBalancerPort(v int64) *Listener {
	s.LoadBalancerPort = &v
	return s
}

// SetProtocol sets the Protocol field's value.
func (s *Listener) SetProtocol(v string) *Listener {
	s.Protocol = &v
	return s
}

// SetSSLCertificateId sets the SSLCertificateId field's value.
func (s *Listener) SetSSLCertificateId(v string) *Listener {
	s.SSLCertificateId = &v
	return s
}

// The policies enabled for a listener.
type ListenerDescription struct {
	_ struct{} `type:"structure"`

	// The listener.
	Listener *Listener `type:"structure"`

	// The policies. If there are no policies enabled, the list is empty.
	PolicyNames []*string `type:"list"`
}

// String returns the string representation
func (s ListenerDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ListenerDescription) GoString() string {
	return s.String()
}

// SetListener sets the Listener field's value.
func (s *ListenerDescription) SetListener(v *Listener) *ListenerDescription {
	s.Listener = v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *ListenerDescription) SetPolicyNames(v []*string) *ListenerDescription {
	s.PolicyNames = v
	return s
}

// The attributes for a load balancer.
type LoadBalancerAttributes struct {
	_ struct{} `type:"structure"`

	// If enabled, the load balancer captures detailed information of all requests
	// and delivers the information to the Amazon S3 bucket that you specify.
	//
	// For more information, see Enable Access Logs (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-access-logs.html)
	// in the Classic Load Balancers Guide.
	AccessLog *AccessLog `type:"structure"`

	// This parameter is reserved.
	AdditionalAttributes []*AdditionalAttribute `type:"list"`

	// If enabled, the load balancer allows existing requests to complete before
	// the load balancer shifts traffic away from a deregistered or unhealthy instance.
	//
	// For more information, see Configure Connection Draining (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-conn-drain.html)
	// in the Classic Load Balancers Guide.
	ConnectionDraining *ConnectionDraining `type:"structure"`

	// If enabled, the load balancer allows the connections to remain idle (no data
	// is sent over the connection) for the specified duration.
	//
	// By default, Elastic Load Balancing maintains a 60-second idle connection
	// timeout for both front-end and back-end connections of your load balancer.
	// For more information, see Configure Idle Connection Timeout (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/config-idle-timeout.html)
	// in the Classic Load Balancers Guide.
	ConnectionSettings *ConnectionSettings `type:"structure"`

	// If enabled, the load balancer routes the request traffic evenly across all
	// instances regardless of the Availability Zones.
	//
	// For more information, see Configure Cross-Zone Load Balancing (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/enable-disable-crosszone-lb.html)
	// in the Classic Load Balancers Guide.
	CrossZoneLoadBalancing *CrossZoneLoadBalancing `type:"structure"`
}

// String returns the string representation
func (s LoadBalancerAttributes) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LoadBalancerAttributes) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *LoadBalancerAttributes) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "LoadBalancerAttributes"}
	if s.AccessLog != nil {
		if err := s.AccessLog.Validate(); err != nil {
			invalidParams.AddNested("AccessLog", err.(request.ErrInvalidParams))
		}
	}
	if s.ConnectionDraining != nil {
		if err := s.ConnectionDraining.Validate(); err != nil {
			invalidParams.AddNested("ConnectionDraining", err.(request.ErrInvalidParams))
		}
	}
	if s.ConnectionSettings != nil {
		if err := s.ConnectionSettings.Validate(); err != nil {
			invalidParams.AddNested("ConnectionSettings", err.(request.ErrInvalidParams))
		}
	}
	if s.CrossZoneLoadBalancing != nil {
		if err := s.CrossZoneLoadBalancing.Validate(); err != nil {
			invalidParams.AddNested("CrossZoneLoadBalancing", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetAccessLog sets the AccessLog field's value.
func (s *LoadBalancerAttributes) SetAccessLog(v *AccessLog) *LoadBalancerAttributes {
	s.AccessLog = v
	return s
}

// SetAdditionalAttributes sets the AdditionalAttributes field's value.
func (s *LoadBalancerAttributes) SetAdditionalAttributes(v []*AdditionalAttribute) *LoadBalancerAttributes {
	s.AdditionalAttributes = v
	return s
}

// SetConnectionDraining sets the ConnectionDraining field's value.
func (s *LoadBalancerAttributes) SetConnectionDraining(v *ConnectionDraining) *LoadBalancerAttributes {
	s.ConnectionDraining = v
	return s
}

// SetConnectionSettings sets the ConnectionSettings field's value.
func (s *LoadBalancerAttributes) SetConnectionSettings(v *ConnectionSettings) *LoadBalancerAttributes {
	s.ConnectionSettings = v
	return s
}

// SetCrossZoneLoadBalancing sets the CrossZoneLoadBalancing field's value.
func (s *LoadBalancerAttributes) SetCrossZoneLoadBalancing(v *CrossZoneLoadBalancing) *LoadBalancerAttributes {
	s.CrossZoneLoadBalancing = v
	return s
}

// Information about a load balancer.
type LoadBalancerDescription struct {
	_ struct{} `type:"structure"`

	// The Availability Zones for the load balancer.
	AvailabilityZones []*string `type:"list"`

	// Information about your EC2 instances.
	BackendServerDescriptions []*BackendServerDescription `type:"list"`

	// The DNS name of the load balancer.
	//
	// For more information, see Configure a Custom Domain Name (http://docs.aws.amazon.com/elasticloadbalancing/latest/classic/using-domain-names-with-elb.html)
	// in the Classic Load Balancers Guide.
	CanonicalHostedZoneName *string `type:"string"`

	// The ID of the Amazon Route 53 hosted zone for the load balancer.
	CanonicalHostedZoneNameID *string `type:"string"`

	// The date and time the load balancer was created.
	CreatedTime *time.Time `type:"timestamp"`

	// The DNS name of the load balancer.
	DNSName *string `type:"string"`

	// Information about the health checks conducted on the load balancer.
	HealthCheck *HealthCheck `type:"structure"`

	// The IDs of the instances for the load balancer.
	Instances []*Instance `type:"list"`

	// The listeners for the load balancer.
	ListenerDescriptions []*ListenerDescription `type:"list"`

	// The name of the load balancer.
	LoadBalancerName *string `type:"string"`

	// The policies defined for the load balancer.
	Policies *Policies `type:"structure"`

	// The type of load balancer. Valid only for load balancers in a VPC.
	//
	// If Scheme is internet-facing, the load balancer has a public DNS name that
	// resolves to a public IP address.
	//
	// If Scheme is internal, the load balancer has a public DNS name that resolves
	// to a private IP address.
	Scheme *string `type:"string"`

	// The security groups for the load balancer. Valid only for load balancers
	// in a VPC.
	SecurityGroups []*string `type:"list"`

	// The security group for the load balancer, which you can use as part of your
	// inbound rules for your registered instances. To only allow traffic from load
	// balancers, add a security group rule that specifies this source security
	// group as the inbound source.
	SourceSecurityGroup *SourceSecurityGroup `type:"structure"`

	// The IDs of the subnets for the load balancer.
	Subnets []*string `type:"list"`

	// The ID of the VPC for the load balancer.
	VPCId *string `type:"string"`
}

// String returns the string representation
func (s LoadBalancerDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s LoadBalancerDescription) GoString() string {
	return s.String()
}

// SetAvailabilityZones sets the AvailabilityZones field's value.
func (s *LoadBalancerDescription) SetAvailabilityZones(v []*string) *LoadBalancerDescription {
	s.AvailabilityZones = v
	return s
}

// SetBackendServerDescriptions sets the BackendServerDescriptions field's value.
func (s *LoadBalancerDescription) SetBackendServerDescriptions(v []*BackendServerDescription) *LoadBalancerDescription {
	s.BackendServerDescriptions = v
	return s
}

// SetCanonicalHostedZoneName sets the CanonicalHostedZoneName field's value.
func (s *LoadBalancerDescription) SetCanonicalHostedZoneName(v string) *LoadBalancerDescription {
	s.CanonicalHostedZoneName = &v
	return s
}

// SetCanonicalHostedZoneNameID sets the CanonicalHostedZoneNameID field's value.
func (s *LoadBalancerDescription) SetCanonicalHostedZoneNameID(v string) *LoadBalancerDescription {
	s.CanonicalHostedZoneNameID = &v
	return s
}

// SetCreatedTime sets the CreatedTime field's value.
func (s *LoadBalancerDescription) SetCreatedTime(v time.Time) *LoadBalancerDescription {
	s.CreatedTime = &v
	return s
}

// SetDNSName sets the DNSName field's value.
func (s *LoadBalancerDescription) SetDNSName(v string) *LoadBalancerDescription {
	s.DNSName = &v
	return s
}

// SetHealthCheck sets the HealthCheck field's value.
func (s *LoadBalancerDescription) SetHealthCheck(v *HealthCheck) *LoadBalancerDescription {
	s.HealthCheck = v
	return s
}

// SetInstances sets the Instances field's value.
func (s *LoadBalancerDescription) SetInstances(v []*Instance) *LoadBalancerDescription {
	s.Instances = v
	return s
}

// SetListenerDescriptions sets the ListenerDescriptions field's value.
func (s *LoadBalancerDescription) SetListenerDescriptions(v []*ListenerDescription) *LoadBalancerDescription {
	s.ListenerDescriptions = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *LoadBalancerDescription) SetLoadBalancerName(v string) *LoadBalancerDescription {
	s.LoadBalancerName = &v
	return s
}

// SetPolicies sets the Policies field's value.
func (s *LoadBalancerDescription) SetPolicies(v *Policies) *LoadBalancerDescription {
	s.Policies = v
	return s
}

// SetScheme sets the Scheme field's value.
func (s *LoadBalancerDescription) SetScheme(v string) *LoadBalancerDescription {
	s.Scheme = &v
	return s
}

// SetSecurityGroups sets the SecurityGroups field's value.
func (s *LoadBalancerDescription) SetSecurityGroups(v []*string) *LoadBalancerDescription {
	s.SecurityGroups = v
	return s
}

// SetSourceSecurityGroup sets the SourceSecurityGroup field's value.
func (s *LoadBalancerDescription) SetSourceSecurityGroup(v *SourceSecurityGroup) *LoadBalancerDescription {
	s.SourceSecurityGroup = v
	return s
}

// SetSubnets sets the Subnets field's value.
func (s *LoadBalancerDescription) SetSubnets(v []*string) *LoadBalancerDescription {
	s.Subnets = v
	return s
}

// SetVPCId sets the VPCId field's value.
func (s *LoadBalancerDescription) SetVPCId(v string) *LoadBalancerDescription {
	s.VPCId = &v
	return s
}

// Contains the parameters for ModifyLoadBalancerAttributes.
type ModifyLoadBalancerAttributesInput struct {
	_ struct{} `type:"structure"`

	// The attributes for the load balancer.
	//
	// LoadBalancerAttributes is a required field
	LoadBalancerAttributes *LoadBalancerAttributes `type:"structure" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s ModifyLoadBalancerAttributesInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ModifyLoadBalancerAttributesInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *ModifyLoadBalancerAttributesInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "ModifyLoadBalancerAttributesInput"}
	if s.LoadBalancerAttributes == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerAttributes"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.LoadBalancerAttributes != nil {
		if err := s.LoadBalancerAttributes.Validate(); err != nil {
			invalidParams.AddNested("LoadBalancerAttributes", err.(request.ErrInvalidParams))
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerAttributes sets the LoadBalancerAttributes field's value.
func (s *ModifyLoadBalancerAttributesInput) SetLoadBalancerAttributes(v *LoadBalancerAttributes) *ModifyLoadBalancerAttributesInput {
	s.LoadBalancerAttributes = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *ModifyLoadBalancerAttributesInput) SetLoadBalancerName(v string) *ModifyLoadBalancerAttributesInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of ModifyLoadBalancerAttributes.
type ModifyLoadBalancerAttributesOutput struct {
	_ struct{} `type:"structure"`

	// Information about the load balancer attributes.
	LoadBalancerAttributes *LoadBalancerAttributes `type:"structure"`

	// The name of the load balancer.
	LoadBalancerName *string `type:"string"`
}

// String returns the string representation
func (s ModifyLoadBalancerAttributesOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s ModifyLoadBalancerAttributesOutput) GoString() string {
	return s.String()
}

// SetLoadBalancerAttributes sets the LoadBalancerAttributes field's value.
func (s *ModifyLoadBalancerAttributesOutput) SetLoadBalancerAttributes(v *LoadBalancerAttributes) *ModifyLoadBalancerAttributesOutput {
	s.LoadBalancerAttributes = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *ModifyLoadBalancerAttributesOutput) SetLoadBalancerName(v string) *ModifyLoadBalancerAttributesOutput {
	s.LoadBalancerName = &v
	return s
}

// The policies for a load balancer.
type Policies struct {
	_ struct{} `type:"structure"`

	// The stickiness policies created using CreateAppCookieStickinessPolicy.
	AppCookieStickinessPolicies []*AppCookieStickinessPolicy `type:"list"`

	// The stickiness policies created using CreateLBCookieStickinessPolicy.
	LBCookieStickinessPolicies []*LBCookieStickinessPolicy `type:"list"`

	// The policies other than the stickiness policies.
	OtherPolicies []*string `type:"list"`
}

// String returns the string representation
func (s Policies) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Policies) GoString() string {
	return s.String()
}

// SetAppCookieStickinessPolicies sets the AppCookieStickinessPolicies field's value.
func (s *Policies) SetAppCookieStickinessPolicies(v []*AppCookieStickinessPolicy) *Policies {
	s.AppCookieStickinessPolicies = v
	return s
}

// SetLBCookieStickinessPolicies sets the LBCookieStickinessPolicies field's value.
func (s *Policies) SetLBCookieStickinessPolicies(v []*LBCookieStickinessPolicy) *Policies {
	s.LBCookieStickinessPolicies = v
	return s
}

// SetOtherPolicies sets the OtherPolicies field's value.
func (s *Policies) SetOtherPolicies(v []*string) *Policies {
	s.OtherPolicies = v
	return s
}

// Information about a policy attribute.
type PolicyAttribute struct {
	_ struct{} `type:"structure"`

	// The name of the attribute.
	AttributeName *string `type:"string"`

	// The value of the attribute.
	AttributeValue *string `type:"string"`
}

// String returns the string representation
func (s PolicyAttribute) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyAttribute) GoString() string {
	return s.String()
}

// SetAttributeName sets the AttributeName field's value.
func (s *PolicyAttribute) SetAttributeName(v string) *PolicyAttribute {
	s.AttributeName = &v
	return s
}

// SetAttributeValue sets the AttributeValue field's value.
func (s *PolicyAttribute) SetAttributeValue(v string) *PolicyAttribute {
	s.AttributeValue = &v
	return s
}

// Information about a policy attribute.
type PolicyAttributeDescription struct {
	_ struct{} `type:"structure"`

	// The name of the attribute.
	AttributeName *string `type:"string"`

	// The value of the attribute.
	AttributeValue *string `type:"string"`
}

// String returns the string representation
func (s PolicyAttributeDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyAttributeDescription) GoString() string {
	return s.String()
}

// SetAttributeName sets the AttributeName field's value.
func (s *PolicyAttributeDescription) SetAttributeName(v string) *PolicyAttributeDescription {
	s.AttributeName = &v
	return s
}

// SetAttributeValue sets the AttributeValue field's value.
func (s *PolicyAttributeDescription) SetAttributeValue(v string) *PolicyAttributeDescription {
	s.AttributeValue = &v
	return s
}

// Information about a policy attribute type.
type PolicyAttributeTypeDescription struct {
	_ struct{} `type:"structure"`

	// The name of the attribute.
	AttributeName *string `type:"string"`

	// The type of the attribute. For example, Boolean or Integer.
	AttributeType *string `type:"string"`

	// The cardinality of the attribute.
	//
	// Valid values:
	//
	//    * ONE(1) : Single value required
	//
	//    * ZERO_OR_ONE(0..1) : Up to one value is allowed
	//
	//    * ZERO_OR_MORE(0..*) : Optional. Multiple values are allowed
	//
	//    * ONE_OR_MORE(1..*0) : Required. Multiple values are allowed
	Cardinality *string `type:"string"`

	// The default value of the attribute, if applicable.
	DefaultValue *string `type:"string"`

	// A description of the attribute.
	Description *string `type:"string"`
}

// String returns the string representation
func (s PolicyAttributeTypeDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyAttributeTypeDescription) GoString() string {
	return s.String()
}

// SetAttributeName sets the AttributeName field's value.
func (s *PolicyAttributeTypeDescription) SetAttributeName(v string) *PolicyAttributeTypeDescription {
	s.AttributeName = &v
	return s
}

// SetAttributeType sets the AttributeType field's value.
func (s *PolicyAttributeTypeDescription) SetAttributeType(v string) *PolicyAttributeTypeDescription {
	s.AttributeType = &v
	return s
}

// SetCardinality sets the Cardinality field's value.
func (s *PolicyAttributeTypeDescription) SetCardinality(v string) *PolicyAttributeTypeDescription {
	s.Cardinality = &v
	return s
}

// SetDefaultValue sets the DefaultValue field's value.
func (s *PolicyAttributeTypeDescription) SetDefaultValue(v string) *PolicyAttributeTypeDescription {
	s.DefaultValue = &v
	return s
}

// SetDescription sets the Description field's value.
func (s *PolicyAttributeTypeDescription) SetDescription(v string) *PolicyAttributeTypeDescription {
	s.Description = &v
	return s
}

// Information about a policy.
type PolicyDescription struct {
	_ struct{} `type:"structure"`

	// The policy attributes.
	PolicyAttributeDescriptions []*PolicyAttributeDescription `type:"list"`

	// The name of the policy.
	PolicyName *string `type:"string"`

	// The name of the policy type.
	PolicyTypeName *string `type:"string"`
}

// String returns the string representation
func (s PolicyDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyDescription) GoString() string {
	return s.String()
}

// SetPolicyAttributeDescriptions sets the PolicyAttributeDescriptions field's value.
func (s *PolicyDescription) SetPolicyAttributeDescriptions(v []*PolicyAttributeDescription) *PolicyDescription {
	s.PolicyAttributeDescriptions = v
	return s
}

// SetPolicyName sets the PolicyName field's value.
func (s *PolicyDescription) SetPolicyName(v string) *PolicyDescription {
	s.PolicyName = &v
	return s
}

// SetPolicyTypeName sets the PolicyTypeName field's value.
func (s *PolicyDescription) SetPolicyTypeName(v string) *PolicyDescription {
	s.PolicyTypeName = &v
	return s
}

// Information about a policy type.
type PolicyTypeDescription struct {
	_ struct{} `type:"structure"`

	// A description of the policy type.
	Description *string `type:"string"`

	// The description of the policy attributes associated with the policies defined
	// by Elastic Load Balancing.
	PolicyAttributeTypeDescriptions []*PolicyAttributeTypeDescription `type:"list"`

	// The name of the policy type.
	PolicyTypeName *string `type:"string"`
}

// String returns the string representation
func (s PolicyTypeDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s PolicyTypeDescription) GoString() string {
	return s.String()
}

// SetDescription sets the Description field's value.
func (s *PolicyTypeDescription) SetDescription(v string) *PolicyTypeDescription {
	s.Description = &v
	return s
}

// SetPolicyAttributeTypeDescriptions sets the PolicyAttributeTypeDescriptions field's value.
func (s *PolicyTypeDescription) SetPolicyAttributeTypeDescriptions(v []*PolicyAttributeTypeDescription) *PolicyTypeDescription {
	s.PolicyAttributeTypeDescriptions = v
	return s
}

// SetPolicyTypeName sets the PolicyTypeName field's value.
func (s *PolicyTypeDescription) SetPolicyTypeName(v string) *PolicyTypeDescription {
	s.PolicyTypeName = &v
	return s
}

// Contains the parameters for RegisterInstancesWithLoadBalancer.
type RegisterInstancesWithLoadBalancerInput struct {
	_ struct{} `type:"structure"`

	// The IDs of the instances.
	//
	// Instances is a required field
	Instances []*Instance `type:"list" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`
}

// String returns the string representation
func (s RegisterInstancesWithLoadBalancerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RegisterInstancesWithLoadBalancerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *RegisterInstancesWithLoadBalancerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "RegisterInstancesWithLoadBalancerInput"}
	if s.Instances == nil {
		invalidParams.Add(request.NewErrParamRequired("Instances"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstances sets the Instances field's value.
func (s *RegisterInstancesWithLoadBalancerInput) SetInstances(v []*Instance) *RegisterInstancesWithLoadBalancerInput {
	s.Instances = v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *RegisterInstancesWithLoadBalancerInput) SetLoadBalancerName(v string) *RegisterInstancesWithLoadBalancerInput {
	s.LoadBalancerName = &v
	return s
}

// Contains the output of RegisterInstancesWithLoadBalancer.
type RegisterInstancesWithLoadBalancerOutput struct {
	_ struct{} `type:"structure"`

	// The updated list of instances for the load balancer.
	Instances []*Instance `type:"list"`
}

// String returns the string representation
func (s RegisterInstancesWithLoadBalancerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RegisterInstancesWithLoadBalancerOutput) GoString() string {
	return s.String()
}

// SetInstances sets the Instances field's value.
func (s *RegisterInstancesWithLoadBalancerOutput) SetInstances(v []*Instance) *RegisterInstancesWithLoadBalancerOutput {
	s.Instances = v
	return s
}

// Contains the parameters for RemoveTags.
type RemoveTagsInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer. You can specify a maximum of one load balancer
	// name.
	//
	// LoadBalancerNames is a required field
	LoadBalancerNames []*string `type:"list" required:"true"`

	// The list of tag keys to remove.
	//
	// Tags is a required field
	Tags []*TagKeyOnly `min:"1" type:"list" required:"true"`
}

// String returns the string representation
func (s RemoveTagsInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RemoveTagsInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *RemoveTagsInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "RemoveTagsInput"}
	if s.LoadBalancerNames == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerNames"))
	}
	if s.Tags == nil {
		invalidParams.Add(request.NewErrParamRequired("Tags"))
	}
	if s.Tags != nil && len(s.Tags) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Tags", 1))
	}
	if s.Tags != nil {
		for i, v := range s.Tags {
			if v == nil {
				continue
			}
			if err := v.Validate(); err != nil {
				invalidParams.AddNested(fmt.Sprintf("%s[%v]", "Tags", i), err.(request.ErrInvalidParams))
			}
		}
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerNames sets the LoadBalancerNames field's value.
func (s *RemoveTagsInput) SetLoadBalancerNames(v []*string) *RemoveTagsInput {
	s.LoadBalancerNames = v
	return s
}

// SetTags sets the Tags field's value.
func (s *RemoveTagsInput) SetTags(v []*TagKeyOnly) *RemoveTagsInput {
	s.Tags = v
	return s
}

// Contains the output of RemoveTags.
type RemoveTagsOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s RemoveTagsOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s RemoveTagsOutput) GoString() string {
	return s.String()
}

// Contains the parameters for SetLoadBalancerListenerSSLCertificate.
type SetLoadBalancerListenerSSLCertificateInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The port that uses the specified SSL certificate.
	//
	// LoadBalancerPort is a required field
	LoadBalancerPort *int64 `type:"integer" required:"true"`

	// The Amazon Resource Name (ARN) of the SSL certificate.
	//
	// SSLCertificateId is a required field
	SSLCertificateId *string `type:"string" required:"true"`
}

// String returns the string representation
func (s SetLoadBalancerListenerSSLCertificateInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerListenerSSLCertificateInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetLoadBalancerListenerSSLCertificateInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetLoadBalancerListenerSSLCertificateInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.LoadBalancerPort == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerPort"))
	}
	if s.SSLCertificateId == nil {
		invalidParams.Add(request.NewErrParamRequired("SSLCertificateId"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *SetLoadBalancerListenerSSLCertificateInput) SetLoadBalancerName(v string) *SetLoadBalancerListenerSSLCertificateInput {
	s.LoadBalancerName = &v
	return s
}

// SetLoadBalancerPort sets the LoadBalancerPort field's value.
func (s *SetLoadBalancerListenerSSLCertificateInput) SetLoadBalancerPort(v int64) *SetLoadBalancerListenerSSLCertificateInput {
	s.LoadBalancerPort = &v
	return s
}

// SetSSLCertificateId sets the SSLCertificateId field's value.
func (s *SetLoadBalancerListenerSSLCertificateInput) SetSSLCertificateId(v string) *SetLoadBalancerListenerSSLCertificateInput {
	s.SSLCertificateId = &v
	return s
}

// Contains the output of SetLoadBalancerListenerSSLCertificate.
type SetLoadBalancerListenerSSLCertificateOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetLoadBalancerListenerSSLCertificateOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerListenerSSLCertificateOutput) GoString() string {
	return s.String()
}

// Contains the parameters for SetLoadBalancerPoliciesForBackendServer.
type SetLoadBalancerPoliciesForBackendServerInput struct {
	_ struct{} `type:"structure"`

	// The port number associated with the EC2 instance.
	//
	// InstancePort is a required field
	InstancePort *int64 `type:"integer" required:"true"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The names of the policies. If the list is empty, then all current polices
	// are removed from the EC2 instance.
	//
	// PolicyNames is a required field
	PolicyNames []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s SetLoadBalancerPoliciesForBackendServerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerPoliciesForBackendServerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetLoadBalancerPoliciesForBackendServerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetLoadBalancerPoliciesForBackendServerInput"}
	if s.InstancePort == nil {
		invalidParams.Add(request.NewErrParamRequired("InstancePort"))
	}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.PolicyNames == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyNames"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetInstancePort sets the InstancePort field's value.
func (s *SetLoadBalancerPoliciesForBackendServerInput) SetInstancePort(v int64) *SetLoadBalancerPoliciesForBackendServerInput {
	s.InstancePort = &v
	return s
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *SetLoadBalancerPoliciesForBackendServerInput) SetLoadBalancerName(v string) *SetLoadBalancerPoliciesForBackendServerInput {
	s.LoadBalancerName = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *SetLoadBalancerPoliciesForBackendServerInput) SetPolicyNames(v []*string) *SetLoadBalancerPoliciesForBackendServerInput {
	s.PolicyNames = v
	return s
}

// Contains the output of SetLoadBalancerPoliciesForBackendServer.
type SetLoadBalancerPoliciesForBackendServerOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetLoadBalancerPoliciesForBackendServerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerPoliciesForBackendServerOutput) GoString() string {
	return s.String()
}

// Contains the parameters for SetLoadBalancePoliciesOfListener.
type SetLoadBalancerPoliciesOfListenerInput struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	//
	// LoadBalancerName is a required field
	LoadBalancerName *string `type:"string" required:"true"`

	// The external port of the load balancer.
	//
	// LoadBalancerPort is a required field
	LoadBalancerPort *int64 `type:"integer" required:"true"`

	// The names of the policies. This list must include all policies to be enabled.
	// If you omit a policy that is currently enabled, it is disabled. If the list
	// is empty, all current policies are disabled.
	//
	// PolicyNames is a required field
	PolicyNames []*string `type:"list" required:"true"`
}

// String returns the string representation
func (s SetLoadBalancerPoliciesOfListenerInput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerPoliciesOfListenerInput) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *SetLoadBalancerPoliciesOfListenerInput) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "SetLoadBalancerPoliciesOfListenerInput"}
	if s.LoadBalancerName == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerName"))
	}
	if s.LoadBalancerPort == nil {
		invalidParams.Add(request.NewErrParamRequired("LoadBalancerPort"))
	}
	if s.PolicyNames == nil {
		invalidParams.Add(request.NewErrParamRequired("PolicyNames"))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *SetLoadBalancerPoliciesOfListenerInput) SetLoadBalancerName(v string) *SetLoadBalancerPoliciesOfListenerInput {
	s.LoadBalancerName = &v
	return s
}

// SetLoadBalancerPort sets the LoadBalancerPort field's value.
func (s *SetLoadBalancerPoliciesOfListenerInput) SetLoadBalancerPort(v int64) *SetLoadBalancerPoliciesOfListenerInput {
	s.LoadBalancerPort = &v
	return s
}

// SetPolicyNames sets the PolicyNames field's value.
func (s *SetLoadBalancerPoliciesOfListenerInput) SetPolicyNames(v []*string) *SetLoadBalancerPoliciesOfListenerInput {
	s.PolicyNames = v
	return s
}

// Contains the output of SetLoadBalancePoliciesOfListener.
type SetLoadBalancerPoliciesOfListenerOutput struct {
	_ struct{} `type:"structure"`
}

// String returns the string representation
func (s SetLoadBalancerPoliciesOfListenerOutput) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SetLoadBalancerPoliciesOfListenerOutput) GoString() string {
	return s.String()
}

// Information about a source security group.
type SourceSecurityGroup struct {
	_ struct{} `type:"structure"`

	// The name of the security group.
	GroupName *string `type:"string"`

	// The owner of the security group.
	OwnerAlias *string `type:"string"`
}

// String returns the string representation
func (s SourceSecurityGroup) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s SourceSecurityGroup) GoString() string {
	return s.String()
}

// SetGroupName sets the GroupName field's value.
func (s *SourceSecurityGroup) SetGroupName(v string) *SourceSecurityGroup {
	s.GroupName = &v
	return s
}

// SetOwnerAlias sets the OwnerAlias field's value.
func (s *SourceSecurityGroup) SetOwnerAlias(v string) *SourceSecurityGroup {
	s.OwnerAlias = &v
	return s
}

// Information about a tag.
type Tag struct {
	_ struct{} `type:"structure"`

	// The key of the tag.
	//
	// Key is a required field
	Key *string `min:"1" type:"string" required:"true"`

	// The value of the tag.
	Value *string `type:"string"`
}

// String returns the string representation
func (s Tag) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s Tag) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *Tag) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "Tag"}
	if s.Key == nil {
		invalidParams.Add(request.NewErrParamRequired("Key"))
	}
	if s.Key != nil && len(*s.Key) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetKey sets the Key field's value.
func (s *Tag) SetKey(v string) *Tag {
	s.Key = &v
	return s
}

// SetValue sets the Value field's value.
func (s *Tag) SetValue(v string) *Tag {
	s.Value = &v
	return s
}

// The tags associated with a load balancer.
type TagDescription struct {
	_ struct{} `type:"structure"`

	// The name of the load balancer.
	LoadBalancerName *string `type:"string"`

	// The tags.
	Tags []*Tag `min:"1" type:"list"`
}

// String returns the string representation
func (s TagDescription) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TagDescription) GoString() string {
	return s.String()
}

// SetLoadBalancerName sets the LoadBalancerName field's value.
func (s *TagDescription) SetLoadBalancerName(v string) *TagDescription {
	s.LoadBalancerName = &v
	return s
}

// SetTags sets the Tags field's value.
func (s *TagDescription) SetTags(v []*Tag) *TagDescription {
	s.Tags = v
	return s
}

// The key of a tag.
type TagKeyOnly struct {
	_ struct{} `type:"structure"`

	// The name of the key.
	Key *string `min:"1" type:"string"`
}

// String returns the string representation
func (s TagKeyOnly) String() string {
	return awsutil.Prettify(s)
}

// GoString returns the string representation
func (s TagKeyOnly) GoString() string {
	return s.String()
}

// Validate inspects the fields of the type to determine if they are valid.
func (s *TagKeyOnly) Validate() error {
	invalidParams := request.ErrInvalidParams{Context: "TagKeyOnly"}
	if s.Key != nil && len(*s.Key) < 1 {
		invalidParams.Add(request.NewErrParamMinLen("Key", 1))
	}

	if invalidParams.Len() > 0 {
		return invalidParams
	}
	return nil
}

// SetKey sets the Key field's value.
func (s *TagKeyOnly) SetKey(v string) *TagKeyOnly {
	s.Key = &v
	return s
}
