All Downloads are FREE. Search and download functionalities are using the official Maven repository.

software.amazon.awssdk.services.ec2.waiters.DefaultEc2Waiter Maven / Gradle / Ivy

/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
 * the License. A copy of the License is located at
 * 
 * http://aws.amazon.com/apache2.0
 * 
 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
 * and limitations under the License.
 */

package software.amazon.awssdk.services.ec2.waiters;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Consumer;
import software.amazon.awssdk.annotations.Generated;
import software.amazon.awssdk.annotations.SdkInternalApi;
import software.amazon.awssdk.annotations.ThreadSafe;
import software.amazon.awssdk.awscore.AwsRequestOverrideConfiguration;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.ApiName;
import software.amazon.awssdk.core.internal.waiters.WaiterAttribute;
import software.amazon.awssdk.core.retry.backoff.BackoffStrategy;
import software.amazon.awssdk.core.retry.backoff.FixedDelayBackoffStrategy;
import software.amazon.awssdk.core.waiters.Waiter;
import software.amazon.awssdk.core.waiters.WaiterAcceptor;
import software.amazon.awssdk.core.waiters.WaiterOverrideConfiguration;
import software.amazon.awssdk.core.waiters.WaiterResponse;
import software.amazon.awssdk.core.waiters.WaiterState;
import software.amazon.awssdk.services.ec2.Ec2Client;
import software.amazon.awssdk.services.ec2.model.DescribeBundleTasksRequest;
import software.amazon.awssdk.services.ec2.model.DescribeBundleTasksResponse;
import software.amazon.awssdk.services.ec2.model.DescribeConversionTasksRequest;
import software.amazon.awssdk.services.ec2.model.DescribeConversionTasksResponse;
import software.amazon.awssdk.services.ec2.model.DescribeCustomerGatewaysRequest;
import software.amazon.awssdk.services.ec2.model.DescribeCustomerGatewaysResponse;
import software.amazon.awssdk.services.ec2.model.DescribeExportTasksRequest;
import software.amazon.awssdk.services.ec2.model.DescribeExportTasksResponse;
import software.amazon.awssdk.services.ec2.model.DescribeImagesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeImagesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeInstanceStatusRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstanceStatusResponse;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeInstancesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeKeyPairsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeKeyPairsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeNatGatewaysRequest;
import software.amazon.awssdk.services.ec2.model.DescribeNatGatewaysResponse;
import software.amazon.awssdk.services.ec2.model.DescribeNetworkInterfacesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeNetworkInterfacesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeSecurityGroupsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeSnapshotsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeSnapshotsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeSpotInstanceRequestsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeSpotInstanceRequestsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeSubnetsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeSubnetsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeVolumesRequest;
import software.amazon.awssdk.services.ec2.model.DescribeVolumesResponse;
import software.amazon.awssdk.services.ec2.model.DescribeVpcPeeringConnectionsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeVpcPeeringConnectionsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeVpcsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeVpcsResponse;
import software.amazon.awssdk.services.ec2.model.DescribeVpnConnectionsRequest;
import software.amazon.awssdk.services.ec2.model.DescribeVpnConnectionsResponse;
import software.amazon.awssdk.services.ec2.model.Ec2Request;
import software.amazon.awssdk.services.ec2.model.GetPasswordDataRequest;
import software.amazon.awssdk.services.ec2.model.GetPasswordDataResponse;
import software.amazon.awssdk.services.ec2.waiters.internal.WaitersRuntime;
import software.amazon.awssdk.utils.AttributeMap;
import software.amazon.awssdk.utils.SdkAutoCloseable;

@Generated("software.amazon.awssdk:codegen")
@SdkInternalApi
@ThreadSafe
final class DefaultEc2Waiter implements Ec2Waiter {
    private static final WaiterAttribute CLIENT_ATTRIBUTE = new WaiterAttribute<>(SdkAutoCloseable.class);

    private final Ec2Client client;

    private final AttributeMap managedResources;

    private final Waiter instanceExistsWaiter;

    private final Waiter bundleTaskCompleteWaiter;

    private final Waiter conversionTaskCancelledWaiter;

    private final Waiter conversionTaskCompletedWaiter;

    private final Waiter conversionTaskDeletedWaiter;

    private final Waiter customerGatewayAvailableWaiter;

    private final Waiter exportTaskCancelledWaiter;

    private final Waiter exportTaskCompletedWaiter;

    private final Waiter imageExistsWaiter;

    private final Waiter imageAvailableWaiter;

    private final Waiter instanceRunningWaiter;

    private final Waiter instanceStatusOkWaiter;

    private final Waiter instanceStoppedWaiter;

    private final Waiter instanceTerminatedWaiter;

    private final Waiter keyPairExistsWaiter;

    private final Waiter natGatewayAvailableWaiter;

    private final Waiter networkInterfaceAvailableWaiter;

    private final Waiter passwordDataAvailableWaiter;

    private final Waiter snapshotCompletedWaiter;

    private final Waiter securityGroupExistsWaiter;

    private final Waiter spotInstanceRequestFulfilledWaiter;

    private final Waiter subnetAvailableWaiter;

    private final Waiter systemStatusOkWaiter;

    private final Waiter volumeAvailableWaiter;

    private final Waiter volumeDeletedWaiter;

    private final Waiter volumeInUseWaiter;

    private final Waiter vpcAvailableWaiter;

    private final Waiter vpcExistsWaiter;

    private final Waiter vpnConnectionAvailableWaiter;

    private final Waiter vpnConnectionDeletedWaiter;

    private final Waiter vpcPeeringConnectionExistsWaiter;

    private final Waiter vpcPeeringConnectionDeletedWaiter;

    private DefaultEc2Waiter(DefaultBuilder builder) {
        AttributeMap.Builder attributeMapBuilder = AttributeMap.builder();
        if (builder.client == null) {
            this.client = Ec2Client.builder().build();
            attributeMapBuilder.put(CLIENT_ATTRIBUTE, this.client);
        } else {
            this.client = builder.client;
        }
        managedResources = attributeMapBuilder.build();
        this.instanceExistsWaiter = Waiter.builder(DescribeInstancesResponse.class).acceptors(instanceExistsWaiterAcceptors())
                .overrideConfiguration(instanceExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.bundleTaskCompleteWaiter = Waiter.builder(DescribeBundleTasksResponse.class)
                .acceptors(bundleTaskCompleteWaiterAcceptors())
                .overrideConfiguration(bundleTaskCompleteWaiterConfig(builder.overrideConfiguration)).build();
        this.conversionTaskCancelledWaiter = Waiter.builder(DescribeConversionTasksResponse.class)
                .acceptors(conversionTaskCancelledWaiterAcceptors())
                .overrideConfiguration(conversionTaskCancelledWaiterConfig(builder.overrideConfiguration)).build();
        this.conversionTaskCompletedWaiter = Waiter.builder(DescribeConversionTasksResponse.class)
                .acceptors(conversionTaskCompletedWaiterAcceptors())
                .overrideConfiguration(conversionTaskCompletedWaiterConfig(builder.overrideConfiguration)).build();
        this.conversionTaskDeletedWaiter = Waiter.builder(DescribeConversionTasksResponse.class)
                .acceptors(conversionTaskDeletedWaiterAcceptors())
                .overrideConfiguration(conversionTaskDeletedWaiterConfig(builder.overrideConfiguration)).build();
        this.customerGatewayAvailableWaiter = Waiter.builder(DescribeCustomerGatewaysResponse.class)
                .acceptors(customerGatewayAvailableWaiterAcceptors())
                .overrideConfiguration(customerGatewayAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.exportTaskCancelledWaiter = Waiter.builder(DescribeExportTasksResponse.class)
                .acceptors(exportTaskCancelledWaiterAcceptors())
                .overrideConfiguration(exportTaskCancelledWaiterConfig(builder.overrideConfiguration)).build();
        this.exportTaskCompletedWaiter = Waiter.builder(DescribeExportTasksResponse.class)
                .acceptors(exportTaskCompletedWaiterAcceptors())
                .overrideConfiguration(exportTaskCompletedWaiterConfig(builder.overrideConfiguration)).build();
        this.imageExistsWaiter = Waiter.builder(DescribeImagesResponse.class).acceptors(imageExistsWaiterAcceptors())
                .overrideConfiguration(imageExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.imageAvailableWaiter = Waiter.builder(DescribeImagesResponse.class).acceptors(imageAvailableWaiterAcceptors())
                .overrideConfiguration(imageAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.instanceRunningWaiter = Waiter.builder(DescribeInstancesResponse.class).acceptors(instanceRunningWaiterAcceptors())
                .overrideConfiguration(instanceRunningWaiterConfig(builder.overrideConfiguration)).build();
        this.instanceStatusOkWaiter = Waiter.builder(DescribeInstanceStatusResponse.class)
                .acceptors(instanceStatusOkWaiterAcceptors())
                .overrideConfiguration(instanceStatusOkWaiterConfig(builder.overrideConfiguration)).build();
        this.instanceStoppedWaiter = Waiter.builder(DescribeInstancesResponse.class).acceptors(instanceStoppedWaiterAcceptors())
                .overrideConfiguration(instanceStoppedWaiterConfig(builder.overrideConfiguration)).build();
        this.instanceTerminatedWaiter = Waiter.builder(DescribeInstancesResponse.class)
                .acceptors(instanceTerminatedWaiterAcceptors())
                .overrideConfiguration(instanceTerminatedWaiterConfig(builder.overrideConfiguration)).build();
        this.keyPairExistsWaiter = Waiter.builder(DescribeKeyPairsResponse.class).acceptors(keyPairExistsWaiterAcceptors())
                .overrideConfiguration(keyPairExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.natGatewayAvailableWaiter = Waiter.builder(DescribeNatGatewaysResponse.class)
                .acceptors(natGatewayAvailableWaiterAcceptors())
                .overrideConfiguration(natGatewayAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.networkInterfaceAvailableWaiter = Waiter.builder(DescribeNetworkInterfacesResponse.class)
                .acceptors(networkInterfaceAvailableWaiterAcceptors())
                .overrideConfiguration(networkInterfaceAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.passwordDataAvailableWaiter = Waiter.builder(GetPasswordDataResponse.class)
                .acceptors(passwordDataAvailableWaiterAcceptors())
                .overrideConfiguration(passwordDataAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.snapshotCompletedWaiter = Waiter.builder(DescribeSnapshotsResponse.class)
                .acceptors(snapshotCompletedWaiterAcceptors())
                .overrideConfiguration(snapshotCompletedWaiterConfig(builder.overrideConfiguration)).build();
        this.securityGroupExistsWaiter = Waiter.builder(DescribeSecurityGroupsResponse.class)
                .acceptors(securityGroupExistsWaiterAcceptors())
                .overrideConfiguration(securityGroupExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.spotInstanceRequestFulfilledWaiter = Waiter.builder(DescribeSpotInstanceRequestsResponse.class)
                .acceptors(spotInstanceRequestFulfilledWaiterAcceptors())
                .overrideConfiguration(spotInstanceRequestFulfilledWaiterConfig(builder.overrideConfiguration)).build();
        this.subnetAvailableWaiter = Waiter.builder(DescribeSubnetsResponse.class).acceptors(subnetAvailableWaiterAcceptors())
                .overrideConfiguration(subnetAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.systemStatusOkWaiter = Waiter.builder(DescribeInstanceStatusResponse.class)
                .acceptors(systemStatusOkWaiterAcceptors())
                .overrideConfiguration(systemStatusOkWaiterConfig(builder.overrideConfiguration)).build();
        this.volumeAvailableWaiter = Waiter.builder(DescribeVolumesResponse.class).acceptors(volumeAvailableWaiterAcceptors())
                .overrideConfiguration(volumeAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.volumeDeletedWaiter = Waiter.builder(DescribeVolumesResponse.class).acceptors(volumeDeletedWaiterAcceptors())
                .overrideConfiguration(volumeDeletedWaiterConfig(builder.overrideConfiguration)).build();
        this.volumeInUseWaiter = Waiter.builder(DescribeVolumesResponse.class).acceptors(volumeInUseWaiterAcceptors())
                .overrideConfiguration(volumeInUseWaiterConfig(builder.overrideConfiguration)).build();
        this.vpcAvailableWaiter = Waiter.builder(DescribeVpcsResponse.class).acceptors(vpcAvailableWaiterAcceptors())
                .overrideConfiguration(vpcAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.vpcExistsWaiter = Waiter.builder(DescribeVpcsResponse.class).acceptors(vpcExistsWaiterAcceptors())
                .overrideConfiguration(vpcExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.vpnConnectionAvailableWaiter = Waiter.builder(DescribeVpnConnectionsResponse.class)
                .acceptors(vpnConnectionAvailableWaiterAcceptors())
                .overrideConfiguration(vpnConnectionAvailableWaiterConfig(builder.overrideConfiguration)).build();
        this.vpnConnectionDeletedWaiter = Waiter.builder(DescribeVpnConnectionsResponse.class)
                .acceptors(vpnConnectionDeletedWaiterAcceptors())
                .overrideConfiguration(vpnConnectionDeletedWaiterConfig(builder.overrideConfiguration)).build();
        this.vpcPeeringConnectionExistsWaiter = Waiter.builder(DescribeVpcPeeringConnectionsResponse.class)
                .acceptors(vpcPeeringConnectionExistsWaiterAcceptors())
                .overrideConfiguration(vpcPeeringConnectionExistsWaiterConfig(builder.overrideConfiguration)).build();
        this.vpcPeeringConnectionDeletedWaiter = Waiter.builder(DescribeVpcPeeringConnectionsResponse.class)
                .acceptors(vpcPeeringConnectionDeletedWaiterAcceptors())
                .overrideConfiguration(vpcPeeringConnectionDeletedWaiterConfig(builder.overrideConfiguration)).build();
    }

    private static String errorCode(Throwable error) {
        if (error instanceof AwsServiceException) {
            return ((AwsServiceException) error).awsErrorDetails().errorCode();
        }
        return null;
    }

    @Override
    public WaiterResponse waitUntilBundleTaskComplete(
            DescribeBundleTasksRequest describeBundleTasksRequest) {
        return bundleTaskCompleteWaiter.run(() -> client.describeBundleTasks(applyWaitersUserAgent(describeBundleTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilBundleTaskComplete(
            DescribeBundleTasksRequest describeBundleTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return bundleTaskCompleteWaiter.run(() -> client.describeBundleTasks(applyWaitersUserAgent(describeBundleTasksRequest)),
                bundleTaskCompleteWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskCancelled(
            DescribeConversionTasksRequest describeConversionTasksRequest) {
        return conversionTaskCancelledWaiter.run(() -> client
                .describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskCancelled(
            DescribeConversionTasksRequest describeConversionTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return conversionTaskCancelledWaiter.run(
                () -> client.describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)),
                conversionTaskCancelledWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskCompleted(
            DescribeConversionTasksRequest describeConversionTasksRequest) {
        return conversionTaskCompletedWaiter.run(() -> client
                .describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskCompleted(
            DescribeConversionTasksRequest describeConversionTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return conversionTaskCompletedWaiter.run(
                () -> client.describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)),
                conversionTaskCompletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskDeleted(
            DescribeConversionTasksRequest describeConversionTasksRequest) {
        return conversionTaskDeletedWaiter.run(() -> client
                .describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilConversionTaskDeleted(
            DescribeConversionTasksRequest describeConversionTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return conversionTaskDeletedWaiter.run(
                () -> client.describeConversionTasks(applyWaitersUserAgent(describeConversionTasksRequest)),
                conversionTaskDeletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilCustomerGatewayAvailable(
            DescribeCustomerGatewaysRequest describeCustomerGatewaysRequest) {
        return customerGatewayAvailableWaiter.run(() -> client
                .describeCustomerGateways(applyWaitersUserAgent(describeCustomerGatewaysRequest)));
    }

    @Override
    public WaiterResponse waitUntilCustomerGatewayAvailable(
            DescribeCustomerGatewaysRequest describeCustomerGatewaysRequest, WaiterOverrideConfiguration overrideConfig) {
        return customerGatewayAvailableWaiter.run(
                () -> client.describeCustomerGateways(applyWaitersUserAgent(describeCustomerGatewaysRequest)),
                customerGatewayAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilExportTaskCancelled(
            DescribeExportTasksRequest describeExportTasksRequest) {
        return exportTaskCancelledWaiter.run(() -> client.describeExportTasks(applyWaitersUserAgent(describeExportTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilExportTaskCancelled(
            DescribeExportTasksRequest describeExportTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return exportTaskCancelledWaiter.run(() -> client.describeExportTasks(applyWaitersUserAgent(describeExportTasksRequest)),
                exportTaskCancelledWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilExportTaskCompleted(
            DescribeExportTasksRequest describeExportTasksRequest) {
        return exportTaskCompletedWaiter.run(() -> client.describeExportTasks(applyWaitersUserAgent(describeExportTasksRequest)));
    }

    @Override
    public WaiterResponse waitUntilExportTaskCompleted(
            DescribeExportTasksRequest describeExportTasksRequest, WaiterOverrideConfiguration overrideConfig) {
        return exportTaskCompletedWaiter.run(() -> client.describeExportTasks(applyWaitersUserAgent(describeExportTasksRequest)),
                exportTaskCompletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilImageAvailable(DescribeImagesRequest describeImagesRequest) {
        return imageAvailableWaiter.run(() -> client.describeImages(applyWaitersUserAgent(describeImagesRequest)));
    }

    @Override
    public WaiterResponse waitUntilImageAvailable(DescribeImagesRequest describeImagesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return imageAvailableWaiter.run(() -> client.describeImages(applyWaitersUserAgent(describeImagesRequest)),
                imageAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilImageExists(DescribeImagesRequest describeImagesRequest) {
        return imageExistsWaiter.run(() -> client.describeImages(applyWaitersUserAgent(describeImagesRequest)));
    }

    @Override
    public WaiterResponse waitUntilImageExists(DescribeImagesRequest describeImagesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return imageExistsWaiter.run(() -> client.describeImages(applyWaitersUserAgent(describeImagesRequest)),
                imageExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilInstanceExists(DescribeInstancesRequest describeInstancesRequest) {
        return instanceExistsWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)));
    }

    @Override
    public WaiterResponse waitUntilInstanceExists(DescribeInstancesRequest describeInstancesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return instanceExistsWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)),
                instanceExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilInstanceRunning(DescribeInstancesRequest describeInstancesRequest) {
        return instanceRunningWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)));
    }

    @Override
    public WaiterResponse waitUntilInstanceRunning(DescribeInstancesRequest describeInstancesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return instanceRunningWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)),
                instanceRunningWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilInstanceStatusOk(
            DescribeInstanceStatusRequest describeInstanceStatusRequest) {
        return instanceStatusOkWaiter.run(() -> client
                .describeInstanceStatus(applyWaitersUserAgent(describeInstanceStatusRequest)));
    }

    @Override
    public WaiterResponse waitUntilInstanceStatusOk(
            DescribeInstanceStatusRequest describeInstanceStatusRequest, WaiterOverrideConfiguration overrideConfig) {
        return instanceStatusOkWaiter.run(
                () -> client.describeInstanceStatus(applyWaitersUserAgent(describeInstanceStatusRequest)),
                instanceStatusOkWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilInstanceStopped(DescribeInstancesRequest describeInstancesRequest) {
        return instanceStoppedWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)));
    }

    @Override
    public WaiterResponse waitUntilInstanceStopped(DescribeInstancesRequest describeInstancesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return instanceStoppedWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)),
                instanceStoppedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilInstanceTerminated(DescribeInstancesRequest describeInstancesRequest) {
        return instanceTerminatedWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)));
    }

    @Override
    public WaiterResponse waitUntilInstanceTerminated(
            DescribeInstancesRequest describeInstancesRequest, WaiterOverrideConfiguration overrideConfig) {
        return instanceTerminatedWaiter.run(() -> client.describeInstances(applyWaitersUserAgent(describeInstancesRequest)),
                instanceTerminatedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilKeyPairExists(DescribeKeyPairsRequest describeKeyPairsRequest) {
        return keyPairExistsWaiter.run(() -> client.describeKeyPairs(applyWaitersUserAgent(describeKeyPairsRequest)));
    }

    @Override
    public WaiterResponse waitUntilKeyPairExists(DescribeKeyPairsRequest describeKeyPairsRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return keyPairExistsWaiter.run(() -> client.describeKeyPairs(applyWaitersUserAgent(describeKeyPairsRequest)),
                keyPairExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilNatGatewayAvailable(
            DescribeNatGatewaysRequest describeNatGatewaysRequest) {
        return natGatewayAvailableWaiter.run(() -> client.describeNatGateways(applyWaitersUserAgent(describeNatGatewaysRequest)));
    }

    @Override
    public WaiterResponse waitUntilNatGatewayAvailable(
            DescribeNatGatewaysRequest describeNatGatewaysRequest, WaiterOverrideConfiguration overrideConfig) {
        return natGatewayAvailableWaiter.run(() -> client.describeNatGateways(applyWaitersUserAgent(describeNatGatewaysRequest)),
                natGatewayAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilNetworkInterfaceAvailable(
            DescribeNetworkInterfacesRequest describeNetworkInterfacesRequest) {
        return networkInterfaceAvailableWaiter.run(() -> client
                .describeNetworkInterfaces(applyWaitersUserAgent(describeNetworkInterfacesRequest)));
    }

    @Override
    public WaiterResponse waitUntilNetworkInterfaceAvailable(
            DescribeNetworkInterfacesRequest describeNetworkInterfacesRequest, WaiterOverrideConfiguration overrideConfig) {
        return networkInterfaceAvailableWaiter.run(
                () -> client.describeNetworkInterfaces(applyWaitersUserAgent(describeNetworkInterfacesRequest)),
                networkInterfaceAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilPasswordDataAvailable(GetPasswordDataRequest getPasswordDataRequest) {
        return passwordDataAvailableWaiter.run(() -> client.getPasswordData(applyWaitersUserAgent(getPasswordDataRequest)));
    }

    @Override
    public WaiterResponse waitUntilPasswordDataAvailable(GetPasswordDataRequest getPasswordDataRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return passwordDataAvailableWaiter.run(() -> client.getPasswordData(applyWaitersUserAgent(getPasswordDataRequest)),
                passwordDataAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilSecurityGroupExists(
            DescribeSecurityGroupsRequest describeSecurityGroupsRequest) {
        return securityGroupExistsWaiter.run(() -> client
                .describeSecurityGroups(applyWaitersUserAgent(describeSecurityGroupsRequest)));
    }

    @Override
    public WaiterResponse waitUntilSecurityGroupExists(
            DescribeSecurityGroupsRequest describeSecurityGroupsRequest, WaiterOverrideConfiguration overrideConfig) {
        return securityGroupExistsWaiter.run(
                () -> client.describeSecurityGroups(applyWaitersUserAgent(describeSecurityGroupsRequest)),
                securityGroupExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilSnapshotCompleted(DescribeSnapshotsRequest describeSnapshotsRequest) {
        return snapshotCompletedWaiter.run(() -> client.describeSnapshots(applyWaitersUserAgent(describeSnapshotsRequest)));
    }

    @Override
    public WaiterResponse waitUntilSnapshotCompleted(
            DescribeSnapshotsRequest describeSnapshotsRequest, WaiterOverrideConfiguration overrideConfig) {
        return snapshotCompletedWaiter.run(() -> client.describeSnapshots(applyWaitersUserAgent(describeSnapshotsRequest)),
                snapshotCompletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilSpotInstanceRequestFulfilled(
            DescribeSpotInstanceRequestsRequest describeSpotInstanceRequestsRequest) {
        return spotInstanceRequestFulfilledWaiter.run(() -> client
                .describeSpotInstanceRequests(applyWaitersUserAgent(describeSpotInstanceRequestsRequest)));
    }

    @Override
    public WaiterResponse waitUntilSpotInstanceRequestFulfilled(
            DescribeSpotInstanceRequestsRequest describeSpotInstanceRequestsRequest, WaiterOverrideConfiguration overrideConfig) {
        return spotInstanceRequestFulfilledWaiter.run(
                () -> client.describeSpotInstanceRequests(applyWaitersUserAgent(describeSpotInstanceRequestsRequest)),
                spotInstanceRequestFulfilledWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilSubnetAvailable(DescribeSubnetsRequest describeSubnetsRequest) {
        return subnetAvailableWaiter.run(() -> client.describeSubnets(applyWaitersUserAgent(describeSubnetsRequest)));
    }

    @Override
    public WaiterResponse waitUntilSubnetAvailable(DescribeSubnetsRequest describeSubnetsRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return subnetAvailableWaiter.run(() -> client.describeSubnets(applyWaitersUserAgent(describeSubnetsRequest)),
                subnetAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilSystemStatusOk(
            DescribeInstanceStatusRequest describeInstanceStatusRequest) {
        return systemStatusOkWaiter
                .run(() -> client.describeInstanceStatus(applyWaitersUserAgent(describeInstanceStatusRequest)));
    }

    @Override
    public WaiterResponse waitUntilSystemStatusOk(
            DescribeInstanceStatusRequest describeInstanceStatusRequest, WaiterOverrideConfiguration overrideConfig) {
        return systemStatusOkWaiter.run(
                () -> client.describeInstanceStatus(applyWaitersUserAgent(describeInstanceStatusRequest)),
                systemStatusOkWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVolumeAvailable(DescribeVolumesRequest describeVolumesRequest) {
        return volumeAvailableWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)));
    }

    @Override
    public WaiterResponse waitUntilVolumeAvailable(DescribeVolumesRequest describeVolumesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return volumeAvailableWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)),
                volumeAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVolumeDeleted(DescribeVolumesRequest describeVolumesRequest) {
        return volumeDeletedWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)));
    }

    @Override
    public WaiterResponse waitUntilVolumeDeleted(DescribeVolumesRequest describeVolumesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return volumeDeletedWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)),
                volumeDeletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVolumeInUse(DescribeVolumesRequest describeVolumesRequest) {
        return volumeInUseWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)));
    }

    @Override
    public WaiterResponse waitUntilVolumeInUse(DescribeVolumesRequest describeVolumesRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return volumeInUseWaiter.run(() -> client.describeVolumes(applyWaitersUserAgent(describeVolumesRequest)),
                volumeInUseWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpcAvailable(DescribeVpcsRequest describeVpcsRequest) {
        return vpcAvailableWaiter.run(() -> client.describeVpcs(applyWaitersUserAgent(describeVpcsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpcAvailable(DescribeVpcsRequest describeVpcsRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return vpcAvailableWaiter.run(() -> client.describeVpcs(applyWaitersUserAgent(describeVpcsRequest)),
                vpcAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpcExists(DescribeVpcsRequest describeVpcsRequest) {
        return vpcExistsWaiter.run(() -> client.describeVpcs(applyWaitersUserAgent(describeVpcsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpcExists(DescribeVpcsRequest describeVpcsRequest,
            WaiterOverrideConfiguration overrideConfig) {
        return vpcExistsWaiter.run(() -> client.describeVpcs(applyWaitersUserAgent(describeVpcsRequest)),
                vpcExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpcPeeringConnectionDeleted(
            DescribeVpcPeeringConnectionsRequest describeVpcPeeringConnectionsRequest) {
        return vpcPeeringConnectionDeletedWaiter.run(() -> client
                .describeVpcPeeringConnections(applyWaitersUserAgent(describeVpcPeeringConnectionsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpcPeeringConnectionDeleted(
            DescribeVpcPeeringConnectionsRequest describeVpcPeeringConnectionsRequest, WaiterOverrideConfiguration overrideConfig) {
        return vpcPeeringConnectionDeletedWaiter.run(
                () -> client.describeVpcPeeringConnections(applyWaitersUserAgent(describeVpcPeeringConnectionsRequest)),
                vpcPeeringConnectionDeletedWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpcPeeringConnectionExists(
            DescribeVpcPeeringConnectionsRequest describeVpcPeeringConnectionsRequest) {
        return vpcPeeringConnectionExistsWaiter.run(() -> client
                .describeVpcPeeringConnections(applyWaitersUserAgent(describeVpcPeeringConnectionsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpcPeeringConnectionExists(
            DescribeVpcPeeringConnectionsRequest describeVpcPeeringConnectionsRequest, WaiterOverrideConfiguration overrideConfig) {
        return vpcPeeringConnectionExistsWaiter.run(
                () -> client.describeVpcPeeringConnections(applyWaitersUserAgent(describeVpcPeeringConnectionsRequest)),
                vpcPeeringConnectionExistsWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpnConnectionAvailable(
            DescribeVpnConnectionsRequest describeVpnConnectionsRequest) {
        return vpnConnectionAvailableWaiter.run(() -> client
                .describeVpnConnections(applyWaitersUserAgent(describeVpnConnectionsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpnConnectionAvailable(
            DescribeVpnConnectionsRequest describeVpnConnectionsRequest, WaiterOverrideConfiguration overrideConfig) {
        return vpnConnectionAvailableWaiter.run(
                () -> client.describeVpnConnections(applyWaitersUserAgent(describeVpnConnectionsRequest)),
                vpnConnectionAvailableWaiterConfig(overrideConfig));
    }

    @Override
    public WaiterResponse waitUntilVpnConnectionDeleted(
            DescribeVpnConnectionsRequest describeVpnConnectionsRequest) {
        return vpnConnectionDeletedWaiter.run(() -> client
                .describeVpnConnections(applyWaitersUserAgent(describeVpnConnectionsRequest)));
    }

    @Override
    public WaiterResponse waitUntilVpnConnectionDeleted(
            DescribeVpnConnectionsRequest describeVpnConnectionsRequest, WaiterOverrideConfiguration overrideConfig) {
        return vpnConnectionDeletedWaiter.run(
                () -> client.describeVpnConnections(applyWaitersUserAgent(describeVpnConnectionsRequest)),
                vpnConnectionDeletedWaiterConfig(overrideConfig));
    }

    private static List> instanceExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            return Objects.equals(input.field("Reservations").flatten().length().compare(">", input.constant(0)).value(), true);
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects
                .equals(errorCode(error), "InvalidInstanceID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> bundleTaskCompleteWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("BundleTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "complete"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("BundleTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "failed"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> conversionTaskCancelledWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ConversionTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "cancelled"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> conversionTaskCompletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ConversionTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "completed"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ConversionTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "cancelled"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ConversionTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "cancelling"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> conversionTaskDeletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ConversionTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> customerGatewayAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("CustomerGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("CustomerGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("CustomerGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleting"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> exportTaskCancelledWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ExportTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "cancelled"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> exportTaskCompletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("ExportTasks").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "completed"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> imageExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            return Objects.equals(input.field("Images").flatten().length().compare(">", input.constant(0)).value(), true);
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "InvalidAMIID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> imageAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Images").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Images").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "failed"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> instanceRunningWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "running"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "shutting-down"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "terminated"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "stopping"));
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects
                .equals(errorCode(error), "InvalidInstanceID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> instanceStatusOkWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("InstanceStatuses").flatten().field("InstanceStatus").field("Status")
                    .values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "ok"));
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects
                .equals(errorCode(error), "InvalidInstanceID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> instanceStoppedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "stopped"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "pending"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "terminated"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> instanceTerminatedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "terminated"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "pending"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Reservations").flatten().field("Instances").flatten().field("State")
                    .field("Name").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "stopping"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> keyPairExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            return Objects.equals(input.field("KeyPairs").flatten().field("KeyName").length().compare(">", input.constant(0))
                    .value(), true);
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "InvalidKeyPair.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> natGatewayAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("NatGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("NatGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "failed"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("NatGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleting"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("NatGateways").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "NatGatewayNotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> networkInterfaceAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("NetworkInterfaces").flatten().field("Status").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnExceptionAcceptor(error -> Objects.equals(errorCode(error),
                "InvalidNetworkInterfaceID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> passwordDataAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            return Objects.equals(input.field("PasswordData").length().compare(">", input.constant(0)).value(), true);
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> snapshotCompletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Snapshots").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "completed"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> securityGroupExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            return Objects.equals(
                    input.field("SecurityGroups").flatten().field("GroupId").length().compare(">", input.constant(0)).value(),
                    true);
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "InvalidGroupNotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> spotInstanceRequestFulfilledWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "fulfilled"));
        }));
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty()
                    && resultValues.stream().allMatch(v -> Objects.equals(v, "request-canceled-and-instance-running"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "schedule-expired"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty()
                    && resultValues.stream().anyMatch(v -> Objects.equals(v, "canceled-before-fulfillment"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "bad-parameters"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("SpotInstanceRequests").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "system-error"));
        }));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error),
                "InvalidSpotInstanceRequestID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> subnetAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Subnets").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> systemStatusOkWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("InstanceStatuses").flatten().field("SystemStatus").field("Status").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "ok"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> volumeAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Volumes").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Volumes").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> volumeDeletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Volumes").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.add(WaiterAcceptor.successOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "InvalidVolume.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> volumeInUseWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Volumes").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "in-use"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Volumes").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpcAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("Vpcs").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpcExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(new WaitersRuntime.ResponseStatusAcceptor(200, WaiterState.SUCCESS));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error), "InvalidVpcID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpnConnectionAvailableWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpnConnections").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "available"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpnConnections").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleting"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpnConnections").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpnConnectionDeletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpnConnections").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.add(WaiterAcceptor.errorOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpnConnections").flatten().field("State").values();
            return !resultValues.isEmpty() && resultValues.stream().anyMatch(v -> Objects.equals(v, "pending"));
        }));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpcPeeringConnectionExistsWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(new WaitersRuntime.ResponseStatusAcceptor(200, WaiterState.SUCCESS));
        result.add(WaiterAcceptor.retryOnExceptionAcceptor(error -> Objects.equals(errorCode(error),
                "InvalidVpcPeeringConnectionID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static List> vpcPeeringConnectionDeletedWaiterAcceptors() {
        List> result = new ArrayList<>();
        result.add(WaiterAcceptor.successOnResponseAcceptor(response -> {
            WaitersRuntime.Value input = new WaitersRuntime.Value(response);
            List resultValues = input.field("VpcPeeringConnections").flatten().field("Status").field("Code").values();
            return !resultValues.isEmpty() && resultValues.stream().allMatch(v -> Objects.equals(v, "deleted"));
        }));
        result.add(WaiterAcceptor.successOnExceptionAcceptor(error -> Objects.equals(errorCode(error),
                "InvalidVpcPeeringConnectionID.NotFound")));
        result.addAll(WaitersRuntime.DEFAULT_ACCEPTORS);
        return result;
    }

    private static WaiterOverrideConfiguration instanceExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(5)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration bundleTaskCompleteWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration conversionTaskCancelledWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration conversionTaskCompletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration conversionTaskDeletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration customerGatewayAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration exportTaskCancelledWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration exportTaskCompletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration imageExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration imageAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration instanceRunningWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration instanceStatusOkWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration instanceStoppedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration instanceTerminatedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration keyPairExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(6);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(5)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration natGatewayAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration networkInterfaceAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(10);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(20)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration passwordDataAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration snapshotCompletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration securityGroupExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(6);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(5)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration spotInstanceRequestFulfilledWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration subnetAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration systemStatusOkWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration volumeAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration volumeDeletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration volumeInUseWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpcAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpcExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(5);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(1)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpnConnectionAvailableWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpnConnectionDeletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpcPeeringConnectionExistsWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    private static WaiterOverrideConfiguration vpcPeeringConnectionDeletedWaiterConfig(WaiterOverrideConfiguration overrideConfig) {
        Optional optionalOverrideConfig = Optional.ofNullable(overrideConfig);
        int maxAttempts = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::maxAttempts).orElse(40);
        BackoffStrategy backoffStrategy = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::backoffStrategy).orElse(
                FixedDelayBackoffStrategy.create(Duration.ofSeconds(15)));
        Duration waitTimeout = optionalOverrideConfig.flatMap(WaiterOverrideConfiguration::waitTimeout).orElse(null);
        return WaiterOverrideConfiguration.builder().maxAttempts(maxAttempts).backoffStrategy(backoffStrategy)
                .waitTimeout(waitTimeout).build();
    }

    @Override
    public void close() {
        managedResources.close();
    }

    public static Ec2Waiter.Builder builder() {
        return new DefaultBuilder();
    }

    private  T applyWaitersUserAgent(T request) {
        Consumer userAgentApplier = b -> b.addApiName(ApiName.builder()
                .version("waiter").name("hll").build());
        AwsRequestOverrideConfiguration overrideConfiguration = request.overrideConfiguration()
                .map(c -> c.toBuilder().applyMutation(userAgentApplier).build())
                .orElse((AwsRequestOverrideConfiguration.builder().applyMutation(userAgentApplier).build()));
        return (T) request.toBuilder().overrideConfiguration(overrideConfiguration).build();
    }

    public static final class DefaultBuilder implements Ec2Waiter.Builder {
        private Ec2Client client;

        private WaiterOverrideConfiguration overrideConfiguration;

        private DefaultBuilder() {
        }

        @Override
        public Ec2Waiter.Builder overrideConfiguration(WaiterOverrideConfiguration overrideConfiguration) {
            this.overrideConfiguration = overrideConfiguration;
            return this;
        }

        @Override
        public Ec2Waiter.Builder client(Ec2Client client) {
            this.client = client;
            return this;
        }

        public Ec2Waiter build() {
            return new DefaultEc2Waiter(this);
        }
    }
}