// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

/**
 * AmazonEC2Skeleton.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: 1.5.6  Built on : Aug 30, 2011 (10:00:16 CEST)
 */
package com.amazon.ec2;

/**
 *  AmazonEC2Skeleton java skeleton for the axisService
 */
public class AmazonEC2Skeleton implements AmazonEC2SkeletonInterface {

    /**
     * Auto generated method signature
     *
                                 * @param describePlacementGroups0
     */

    public com.amazon.ec2.DescribePlacementGroupsResponse describePlacementGroups(com.amazon.ec2.DescribePlacementGroups describePlacementGroups0) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describePlacementGroups");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createSecurityGroup2
     */

    public com.amazon.ec2.CreateSecurityGroupResponse createSecurityGroup(com.amazon.ec2.CreateSecurityGroup createSecurityGroup2) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createSecurityGroup");
    }

    /**
     * Auto generated method signature
     *
                                 * @param resetNetworkInterfaceAttribute4
     */

    public com.amazon.ec2.ResetNetworkInterfaceAttributeResponse resetNetworkInterfaceAttribute(
        com.amazon.ec2.ResetNetworkInterfaceAttribute resetNetworkInterfaceAttribute4) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#resetNetworkInterfaceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createDhcpOptions6
     */

    public com.amazon.ec2.CreateDhcpOptionsResponse createDhcpOptions(com.amazon.ec2.CreateDhcpOptions createDhcpOptions6) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createDhcpOptions");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createRouteTable8
     */

    public com.amazon.ec2.CreateRouteTableResponse createRouteTable(com.amazon.ec2.CreateRouteTable createRouteTable8) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createRouteTable");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSubnets10
     */

    public com.amazon.ec2.DescribeSubnetsResponse describeSubnets(com.amazon.ec2.DescribeSubnets describeSubnets10) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSubnets");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deactivateLicense12
     */

    public com.amazon.ec2.DeactivateLicenseResponse deactivateLicense(com.amazon.ec2.DeactivateLicense deactivateLicense12) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deactivateLicense");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteVpc14
     */

    public com.amazon.ec2.DeleteVpcResponse deleteVpc(com.amazon.ec2.DeleteVpc deleteVpc14) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteVpc");
    }

    /**
     * Auto generated method signature
     *
                                 * @param cancelSpotInstanceRequests16
     */

    public com.amazon.ec2.CancelSpotInstanceRequestsResponse cancelSpotInstanceRequests(com.amazon.ec2.CancelSpotInstanceRequests cancelSpotInstanceRequests16) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#cancelSpotInstanceRequests");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createSubnet18
     */

    public com.amazon.ec2.CreateSubnetResponse createSubnet(com.amazon.ec2.CreateSubnet createSubnet18) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createSubnet");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteVpnGateway20
     */

    public com.amazon.ec2.DeleteVpnGatewayResponse deleteVpnGateway(com.amazon.ec2.DeleteVpnGateway deleteVpnGateway20) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteVpnGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createNetworkAclEntry22
     */

    public com.amazon.ec2.CreateNetworkAclEntryResponse createNetworkAclEntry(com.amazon.ec2.CreateNetworkAclEntry createNetworkAclEntry22) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createNetworkAclEntry");
    }

    /**
     * Auto generated method signature
     *
                                 * @param requestSpotInstances24
     */

    public com.amazon.ec2.RequestSpotInstancesResponse requestSpotInstances(com.amazon.ec2.RequestSpotInstances requestSpotInstances24) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#requestSpotInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVolumeAttribute26
     */

    public com.amazon.ec2.DescribeVolumeAttributeResponse describeVolumeAttribute(com.amazon.ec2.DescribeVolumeAttribute describeVolumeAttribute26) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVolumeAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param associateDhcpOptions28
     */

    public com.amazon.ec2.AssociateDhcpOptionsResponse associateDhcpOptions(com.amazon.ec2.AssociateDhcpOptions associateDhcpOptions28) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#associateDhcpOptions");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeTags30
     */

    public com.amazon.ec2.DescribeTagsResponse describeTags(com.amazon.ec2.DescribeTags describeTags30) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeTags");
    }

    /**
     * Auto generated method signature
     *
                                 * @param importKeyPair32
     */

    public com.amazon.ec2.ImportKeyPairResponse importKeyPair(com.amazon.ec2.ImportKeyPair importKeyPair32) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#importKeyPair");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteNetworkInterface34
     */

    public com.amazon.ec2.DeleteNetworkInterfaceResponse deleteNetworkInterface(com.amazon.ec2.DeleteNetworkInterface deleteNetworkInterface34) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteNetworkInterface");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVpcs36
     */

    public com.amazon.ec2.DescribeVpcsResponse describeVpcs(com.amazon.ec2.DescribeVpcs describeVpcs36) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVpcs");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeLicenses38
     */

    public com.amazon.ec2.DescribeLicensesResponse describeLicenses(com.amazon.ec2.DescribeLicenses describeLicenses38) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeLicenses");
    }

    /**
     * Auto generated method signature
     *
                                 * @param bundleInstance40
     */

    public com.amazon.ec2.BundleInstanceResponse bundleInstance(com.amazon.ec2.BundleInstance bundleInstance40) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#bundleInstance");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVpnConnections42
     */

    public com.amazon.ec2.DescribeVpnConnectionsResponse describeVpnConnections(com.amazon.ec2.DescribeVpnConnections describeVpnConnections42) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVpnConnections");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeImages44
     */

    public com.amazon.ec2.DescribeImagesResponse describeImages(com.amazon.ec2.DescribeImages describeImages44) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeImages");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createInternetGateway46
     */

    public com.amazon.ec2.CreateInternetGatewayResponse createInternetGateway(com.amazon.ec2.CreateInternetGateway createInternetGateway46) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createInternetGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param disassociateRouteTable48
     */

    public com.amazon.ec2.DisassociateRouteTableResponse disassociateRouteTable(com.amazon.ec2.DisassociateRouteTable disassociateRouteTable48) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#disassociateRouteTable");
    }

    /**
     * Auto generated method signature
     *
                                 * @param replaceNetworkAclEntry50
     */

    public com.amazon.ec2.ReplaceNetworkAclEntryResponse replaceNetworkAclEntry(com.amazon.ec2.ReplaceNetworkAclEntry replaceNetworkAclEntry50) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#replaceNetworkAclEntry");
    }

    /**
     * Auto generated method signature
     *
                                 * @param authorizeSecurityGroupIngress52
     */

    public com.amazon.ec2.AuthorizeSecurityGroupIngressResponse
        authorizeSecurityGroupIngress(com.amazon.ec2.AuthorizeSecurityGroupIngress authorizeSecurityGroupIngress52) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#authorizeSecurityGroupIngress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSnapshotAttribute54
     */

    public com.amazon.ec2.DescribeSnapshotAttributeResponse describeSnapshotAttribute(com.amazon.ec2.DescribeSnapshotAttribute describeSnapshotAttribute54) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSnapshotAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createVpnGateway56
     */

    public com.amazon.ec2.CreateVpnGatewayResponse createVpnGateway(com.amazon.ec2.CreateVpnGateway createVpnGateway56) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createVpnGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param resetInstanceAttribute58
     */

    public com.amazon.ec2.ResetInstanceAttributeResponse resetInstanceAttribute(com.amazon.ec2.ResetInstanceAttribute resetInstanceAttribute58) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#resetInstanceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createTags60
     */

    public com.amazon.ec2.CreateTagsResponse createTags(com.amazon.ec2.CreateTags createTags60) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createTags");
    }

    /**
     * Auto generated method signature
     *
                                 * @param authorizeSecurityGroupEgress62
     */

    public com.amazon.ec2.AuthorizeSecurityGroupEgressResponse authorizeSecurityGroupEgress(com.amazon.ec2.AuthorizeSecurityGroupEgress authorizeSecurityGroupEgress62) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#authorizeSecurityGroupEgress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param associateAddress64
     */

    public com.amazon.ec2.AssociateAddressResponse associateAddress(com.amazon.ec2.AssociateAddress associateAddress64) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#associateAddress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeImageAttribute66
     */

    public com.amazon.ec2.DescribeImageAttributeResponse describeImageAttribute(com.amazon.ec2.DescribeImageAttribute describeImageAttribute66) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeImageAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSpotPriceHistory68
     */

    public com.amazon.ec2.DescribeSpotPriceHistoryResponse describeSpotPriceHistory(com.amazon.ec2.DescribeSpotPriceHistory describeSpotPriceHistory68) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSpotPriceHistory");
    }

    /**
     * Auto generated method signature
     *
                                 * @param modifySnapshotAttribute70
     */

    public com.amazon.ec2.ModifySnapshotAttributeResponse modifySnapshotAttribute(com.amazon.ec2.ModifySnapshotAttribute modifySnapshotAttribute70) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#modifySnapshotAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSpotInstanceRequests72
     */

    public com.amazon.ec2.DescribeSpotInstanceRequestsResponse describeSpotInstanceRequests(com.amazon.ec2.DescribeSpotInstanceRequests describeSpotInstanceRequests72) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSpotInstanceRequests");
    }

    /**
     * Auto generated method signature
     *
                                 * @param importInstance74
     */

    public com.amazon.ec2.ImportInstanceResponse importInstance(com.amazon.ec2.ImportInstance importInstance74) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#importInstance");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeKeyPairs76
     */

    public com.amazon.ec2.DescribeKeyPairsResponse describeKeyPairs(com.amazon.ec2.DescribeKeyPairs describeKeyPairs76) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeKeyPairs");
    }

    /**
     * Auto generated method signature
     *
                                 * @param revokeSecurityGroupIngress78
     */

    public com.amazon.ec2.RevokeSecurityGroupIngressResponse revokeSecurityGroupIngress(com.amazon.ec2.RevokeSecurityGroupIngress revokeSecurityGroupIngress78) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#revokeSecurityGroupIngress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createPlacementGroup80
     */

    public com.amazon.ec2.CreatePlacementGroupResponse createPlacementGroup(com.amazon.ec2.CreatePlacementGroup createPlacementGroup80) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createPlacementGroup");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteNetworkAclEntry82
     */

    public com.amazon.ec2.DeleteNetworkAclEntryResponse deleteNetworkAclEntry(com.amazon.ec2.DeleteNetworkAclEntry deleteNetworkAclEntry82) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteNetworkAclEntry");
    }

    /**
     * Auto generated method signature
     *
                                 * @param activateLicense84
     */

    public com.amazon.ec2.ActivateLicenseResponse activateLicense(com.amazon.ec2.ActivateLicense activateLicense84) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#activateLicense");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteRouteTable86
     */

    public com.amazon.ec2.DeleteRouteTableResponse deleteRouteTable(com.amazon.ec2.DeleteRouteTable deleteRouteTable86) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteRouteTable");
    }

    /**
     * Auto generated method signature
     *
                                 * @param unmonitorInstances88
     */

    public com.amazon.ec2.UnmonitorInstancesResponse unmonitorInstances(com.amazon.ec2.UnmonitorInstances unmonitorInstances88) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#unmonitorInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param startInstances90
     */

    public com.amazon.ec2.StartInstancesResponse startInstances(com.amazon.ec2.StartInstances startInstances90) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#startInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param confirmProductInstance92
     */

    public com.amazon.ec2.ConfirmProductInstanceResponse confirmProductInstance(com.amazon.ec2.ConfirmProductInstance confirmProductInstance92) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#confirmProductInstance");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeNetworkInterfaceAttribute94
     */

    public com.amazon.ec2.DescribeNetworkInterfaceAttributeResponse describeNetworkInterfaceAttribute(
        com.amazon.ec2.DescribeNetworkInterfaceAttribute describeNetworkInterfaceAttribute94) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeNetworkInterfaceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param runInstances96
     */

    public com.amazon.ec2.RunInstancesResponse runInstances(com.amazon.ec2.RunInstances runInstances96) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#runInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createReservedInstancesListing98
     */

    public com.amazon.ec2.CreateReservedInstancesListingResponse createReservedInstancesListing(
        com.amazon.ec2.CreateReservedInstancesListing createReservedInstancesListing98) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createReservedInstancesListing");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createCustomerGateway100
     */

    public com.amazon.ec2.CreateCustomerGatewayResponse createCustomerGateway(com.amazon.ec2.CreateCustomerGateway createCustomerGateway100) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createCustomerGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createNetworkAcl102
     */

    public com.amazon.ec2.CreateNetworkAclResponse createNetworkAcl(com.amazon.ec2.CreateNetworkAcl createNetworkAcl102) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createNetworkAcl");
    }

    /**
     * Auto generated method signature
     *
                                 * @param resetImageAttribute104
     */

    public com.amazon.ec2.ResetImageAttributeResponse resetImageAttribute(com.amazon.ec2.ResetImageAttribute resetImageAttribute104) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#resetImageAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param modifyVolumeAttribute106
     */

    public com.amazon.ec2.ModifyVolumeAttributeResponse modifyVolumeAttribute(com.amazon.ec2.ModifyVolumeAttribute modifyVolumeAttribute106) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#modifyVolumeAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeReservedInstances108
     */

    public com.amazon.ec2.DescribeReservedInstancesResponse describeReservedInstances(com.amazon.ec2.DescribeReservedInstances describeReservedInstances108) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeReservedInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param resetSnapshotAttribute110
     */

    public com.amazon.ec2.ResetSnapshotAttributeResponse resetSnapshotAttribute(com.amazon.ec2.ResetSnapshotAttribute resetSnapshotAttribute110) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#resetSnapshotAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteVolume112
     */

    public com.amazon.ec2.DeleteVolumeResponse deleteVolume(com.amazon.ec2.DeleteVolume deleteVolume112) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteVolume");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeAvailabilityZones114
     */

    public com.amazon.ec2.DescribeAvailabilityZonesResponse describeAvailabilityZones(com.amazon.ec2.DescribeAvailabilityZones describeAvailabilityZones114) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeAvailabilityZones");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createVpnConnection116
     */

    public com.amazon.ec2.CreateVpnConnectionResponse createVpnConnection(com.amazon.ec2.CreateVpnConnection createVpnConnection116) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createVpnConnection");
    }

    /**
     * Auto generated method signature
     *
                                 * @param cancelBundleTask118
     */

    public com.amazon.ec2.CancelBundleTaskResponse cancelBundleTask(com.amazon.ec2.CancelBundleTask cancelBundleTask118) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#cancelBundleTask");
    }

    /**
     * Auto generated method signature
     *
                                 * @param replaceNetworkAclAssociation120
     */

    public com.amazon.ec2.ReplaceNetworkAclAssociationResponse replaceNetworkAclAssociation(com.amazon.ec2.ReplaceNetworkAclAssociation replaceNetworkAclAssociation120) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#replaceNetworkAclAssociation");
    }

    /**
     * Auto generated method signature
     *
                                 * @param detachVpnGateway122
     */

    public com.amazon.ec2.DetachVpnGatewayResponse detachVpnGateway(com.amazon.ec2.DetachVpnGateway detachVpnGateway122) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#detachVpnGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSnapshots124
     */

    public com.amazon.ec2.DescribeSnapshotsResponse describeSnapshots(com.amazon.ec2.DescribeSnapshots describeSnapshots124) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSnapshots");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteSubnet126
     */

    public com.amazon.ec2.DeleteSubnetResponse deleteSubnet(com.amazon.ec2.DeleteSubnet deleteSubnet126) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteSubnet");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeBundleTasks128
     */

    public com.amazon.ec2.DescribeBundleTasksResponse describeBundleTasks(com.amazon.ec2.DescribeBundleTasks describeBundleTasks128) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeBundleTasks");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createKeyPair130
     */

    public com.amazon.ec2.CreateKeyPairResponse createKeyPair(com.amazon.ec2.CreateKeyPair createKeyPair130) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createKeyPair");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createImage132
     */

    public com.amazon.ec2.CreateImageResponse createImage(com.amazon.ec2.CreateImage createImage132) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createImage");
    }

    /**
     * Auto generated method signature
     *
                                 * @param enableVgwRoutePropagation134
     */

    public com.amazon.ec2.EnableVgwRoutePropagationResponse enableVgwRoutePropagation(com.amazon.ec2.EnableVgwRoutePropagation enableVgwRoutePropagation134) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#enableVgwRoutePropagation");
    }

    /**
     * Auto generated method signature
     *
                                 * @param unassignPrivateIpAddresses136
     */

    public com.amazon.ec2.UnassignPrivateIpAddressesResponse unassignPrivateIpAddresses(com.amazon.ec2.UnassignPrivateIpAddresses unassignPrivateIpAddresses136) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#unassignPrivateIpAddresses");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deregisterImage138
     */

    public com.amazon.ec2.DeregisterImageResponse deregisterImage(com.amazon.ec2.DeregisterImage deregisterImage138) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deregisterImage");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteVpnConnectionRoute140
     */

    public com.amazon.ec2.DeleteVpnConnectionRouteResponse deleteVpnConnectionRoute(com.amazon.ec2.DeleteVpnConnectionRoute deleteVpnConnectionRoute140) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteVpnConnectionRoute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param modifyImageAttribute142
     */

    public com.amazon.ec2.ModifyImageAttributeResponse modifyImageAttribute(com.amazon.ec2.ModifyImageAttribute modifyImageAttribute142) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#modifyImageAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param cancelConversionTask144
     */

    public com.amazon.ec2.CancelConversionTaskResponse cancelConversionTask(com.amazon.ec2.CancelConversionTask cancelConversionTask144) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#cancelConversionTask");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVolumes146
     */

    public com.amazon.ec2.DescribeVolumesResponse describeVolumes(com.amazon.ec2.DescribeVolumes describeVolumes146) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVolumes");
    }

    /**
     * Auto generated method signature
     *
                                 * @param cancelReservedInstancesListing148
     */

    public com.amazon.ec2.CancelReservedInstancesListingResponse cancelReservedInstancesListing(
        com.amazon.ec2.CancelReservedInstancesListing cancelReservedInstancesListing148) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#cancelReservedInstancesListing");
    }

    /**
     * Auto generated method signature
     *
                                 * @param getPasswordData150
     */

    public com.amazon.ec2.GetPasswordDataResponse getPasswordData(com.amazon.ec2.GetPasswordData getPasswordData150) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getPasswordData");
    }

    /**
     * Auto generated method signature
     *
                                 * @param allocateAddress152
     */

    public com.amazon.ec2.AllocateAddressResponse allocateAddress(com.amazon.ec2.AllocateAddress allocateAddress152) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#allocateAddress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteSecurityGroup154
     */

    public com.amazon.ec2.DeleteSecurityGroupResponse deleteSecurityGroup(com.amazon.ec2.DeleteSecurityGroup deleteSecurityGroup154) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteSecurityGroup");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deletePlacementGroup156
     */

    public com.amazon.ec2.DeletePlacementGroupResponse deletePlacementGroup(com.amazon.ec2.DeletePlacementGroup deletePlacementGroup156) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deletePlacementGroup");
    }

    /**
     * Auto generated method signature
     *
                                 * @param disassociateAddress158
     */

    public com.amazon.ec2.DisassociateAddressResponse disassociateAddress(com.amazon.ec2.DisassociateAddress disassociateAddress158) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#disassociateAddress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteDhcpOptions160
     */

    public com.amazon.ec2.DeleteDhcpOptionsResponse deleteDhcpOptions(com.amazon.ec2.DeleteDhcpOptions deleteDhcpOptions160) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteDhcpOptions");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSpotDatafeedSubscription162
     */

    public com.amazon.ec2.DescribeSpotDatafeedSubscriptionResponse describeSpotDatafeedSubscription(
        com.amazon.ec2.DescribeSpotDatafeedSubscription describeSpotDatafeedSubscription162) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSpotDatafeedSubscription");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeNetworkAcls164
     */

    public com.amazon.ec2.DescribeNetworkAclsResponse describeNetworkAcls(com.amazon.ec2.DescribeNetworkAcls describeNetworkAcls164) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeNetworkAcls");
    }

    /**
     * Auto generated method signature
     *
                                 * @param enableVolumeIO166
     */

    public com.amazon.ec2.EnableVolumeIOResponse enableVolumeIO(com.amazon.ec2.EnableVolumeIO enableVolumeIO166) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#enableVolumeIO");
    }

    /**
     * Auto generated method signature
     *
                                 * @param attachVpnGateway168
     */

    public com.amazon.ec2.AttachVpnGatewayResponse attachVpnGateway(com.amazon.ec2.AttachVpnGateway attachVpnGateway168) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#attachVpnGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeInternetGateways170
     */

    public com.amazon.ec2.DescribeInternetGatewaysResponse describeInternetGateways(com.amazon.ec2.DescribeInternetGateways describeInternetGateways170) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeInternetGateways");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeDhcpOptions172
     */

    public com.amazon.ec2.DescribeDhcpOptionsResponse describeDhcpOptions(com.amazon.ec2.DescribeDhcpOptions describeDhcpOptions172) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeDhcpOptions");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createSpotDatafeedSubscription174
     */

    public com.amazon.ec2.CreateSpotDatafeedSubscriptionResponse createSpotDatafeedSubscription(
        com.amazon.ec2.CreateSpotDatafeedSubscription createSpotDatafeedSubscription174) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createSpotDatafeedSubscription");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeReservedInstancesListings176
     */

    public com.amazon.ec2.DescribeReservedInstancesListingsResponse describeReservedInstancesListings(
        com.amazon.ec2.DescribeReservedInstancesListings describeReservedInstancesListings176) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeReservedInstancesListings");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeInstanceStatus178
     */

    public com.amazon.ec2.DescribeInstanceStatusResponse describeInstanceStatus(com.amazon.ec2.DescribeInstanceStatus describeInstanceStatus178) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeInstanceStatus");
    }

    /**
     * Auto generated method signature
     *
                                 * @param modifyNetworkInterfaceAttribute180
     */

    public com.amazon.ec2.ModifyNetworkInterfaceAttributeResponse modifyNetworkInterfaceAttribute(
        com.amazon.ec2.ModifyNetworkInterfaceAttribute modifyNetworkInterfaceAttribute180) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#modifyNetworkInterfaceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param disableVgwRoutePropagation182
     */

    public com.amazon.ec2.DisableVgwRoutePropagationResponse disableVgwRoutePropagation(com.amazon.ec2.DisableVgwRoutePropagation disableVgwRoutePropagation182) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#disableVgwRoutePropagation");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVolumeStatus184
     */

    public com.amazon.ec2.DescribeVolumeStatusResponse describeVolumeStatus(com.amazon.ec2.DescribeVolumeStatus describeVolumeStatus184) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVolumeStatus");
    }

    /**
     * Auto generated method signature
     *
                                 * @param detachNetworkInterface186
     */

    public com.amazon.ec2.DetachNetworkInterfaceResponse detachNetworkInterface(com.amazon.ec2.DetachNetworkInterface detachNetworkInterface186) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#detachNetworkInterface");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeSecurityGroups188
     */

    public com.amazon.ec2.DescribeSecurityGroupsResponse describeSecurityGroups(com.amazon.ec2.DescribeSecurityGroups describeSecurityGroups188) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeSecurityGroups");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeInstances190
     */

    public com.amazon.ec2.DescribeInstancesResponse describeInstances(com.amazon.ec2.DescribeInstances describeInstances190) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeNetworkInterfaces192
     */

    public com.amazon.ec2.DescribeNetworkInterfacesResponse describeNetworkInterfaces(com.amazon.ec2.DescribeNetworkInterfaces describeNetworkInterfaces192) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeNetworkInterfaces");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteKeyPair194
     */

    public com.amazon.ec2.DeleteKeyPairResponse deleteKeyPair(com.amazon.ec2.DeleteKeyPair deleteKeyPair194) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteKeyPair");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createSnapshot196
     */

    public com.amazon.ec2.CreateSnapshotResponse createSnapshot(com.amazon.ec2.CreateSnapshot createSnapshot196) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createSnapshot");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeVpnGateways198
     */

    public com.amazon.ec2.DescribeVpnGatewaysResponse describeVpnGateways(com.amazon.ec2.DescribeVpnGateways describeVpnGateways198) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeVpnGateways");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteTags200
     */

    public com.amazon.ec2.DeleteTagsResponse deleteTags(com.amazon.ec2.DeleteTags deleteTags200) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteTags");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteSnapshot202
     */

    public com.amazon.ec2.DeleteSnapshotResponse deleteSnapshot(com.amazon.ec2.DeleteSnapshot deleteSnapshot202) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteSnapshot");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteCustomerGateway204
     */

    public com.amazon.ec2.DeleteCustomerGatewayResponse deleteCustomerGateway(com.amazon.ec2.DeleteCustomerGateway deleteCustomerGateway204) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteCustomerGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createVolume206
     */

    public com.amazon.ec2.CreateVolumeResponse createVolume(com.amazon.ec2.CreateVolume createVolume206) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createVolume");
    }

    /**
     * Auto generated method signature
     *
                                 * @param cancelExportTask208
     */

    public com.amazon.ec2.CancelExportTaskResponse cancelExportTask(com.amazon.ec2.CancelExportTask cancelExportTask208) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#cancelExportTask");
    }

    /**
     * Auto generated method signature
     *
                                 * @param registerImage210
     */

    public com.amazon.ec2.RegisterImageResponse registerImage(com.amazon.ec2.RegisterImage registerImage210) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#registerImage");
    }

    /**
     * Auto generated method signature
     *
                                 * @param detachVolume212
     */

    public com.amazon.ec2.DetachVolumeResponse detachVolume(com.amazon.ec2.DetachVolume detachVolume212) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#detachVolume");
    }

    /**
     * Auto generated method signature
     *
                                 * @param stopInstances214
     */

    public com.amazon.ec2.StopInstancesResponse stopInstances(com.amazon.ec2.StopInstances stopInstances214) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#stopInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createRoute216
     */

    public com.amazon.ec2.CreateRouteResponse createRoute(com.amazon.ec2.CreateRoute createRoute216) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createRoute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param releaseAddress218
     */

    public com.amazon.ec2.ReleaseAddressResponse releaseAddress(com.amazon.ec2.ReleaseAddress releaseAddress218) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#releaseAddress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeRouteTables220
     */

    public com.amazon.ec2.DescribeRouteTablesResponse describeRouteTables(com.amazon.ec2.DescribeRouteTables describeRouteTables220) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeRouteTables");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeCustomerGateways222
     */

    public com.amazon.ec2.DescribeCustomerGatewaysResponse describeCustomerGateways(com.amazon.ec2.DescribeCustomerGateways describeCustomerGateways222) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeCustomerGateways");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteNetworkAcl224
     */

    public com.amazon.ec2.DeleteNetworkAclResponse deleteNetworkAcl(com.amazon.ec2.DeleteNetworkAcl deleteNetworkAcl224) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteNetworkAcl");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteRoute226
     */

    public com.amazon.ec2.DeleteRouteResponse deleteRoute(com.amazon.ec2.DeleteRoute deleteRoute226) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteRoute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param rebootInstances228
     */

    public com.amazon.ec2.RebootInstancesResponse rebootInstances(com.amazon.ec2.RebootInstances rebootInstances228) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#rebootInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param modifyInstanceAttribute230
     */

    public com.amazon.ec2.ModifyInstanceAttributeResponse modifyInstanceAttribute(com.amazon.ec2.ModifyInstanceAttribute modifyInstanceAttribute230) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#modifyInstanceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param terminateInstances232
     */

    public com.amazon.ec2.TerminateInstancesResponse terminateInstances(com.amazon.ec2.TerminateInstances terminateInstances232) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#terminateInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createVpnConnectionRoute234
     */

    public com.amazon.ec2.CreateVpnConnectionRouteResponse createVpnConnectionRoute(com.amazon.ec2.CreateVpnConnectionRoute createVpnConnectionRoute234) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createVpnConnectionRoute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeConversionTasks236
     */

    public com.amazon.ec2.DescribeConversionTasksResponse describeConversionTasks(com.amazon.ec2.DescribeConversionTasks describeConversionTasks236) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeConversionTasks");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeAddresses238
     */

    public com.amazon.ec2.DescribeAddressesResponse describeAddresses(com.amazon.ec2.DescribeAddresses describeAddresses238) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeAddresses");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeInstanceAttribute240
     */

    public com.amazon.ec2.DescribeInstanceAttributeResponse describeInstanceAttribute(com.amazon.ec2.DescribeInstanceAttribute describeInstanceAttribute240) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeInstanceAttribute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param attachInternetGateway242
     */

    public com.amazon.ec2.AttachInternetGatewayResponse attachInternetGateway(com.amazon.ec2.AttachInternetGateway attachInternetGateway242) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#attachInternetGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createVpc244
     */

    public com.amazon.ec2.CreateVpcResponse createVpc(com.amazon.ec2.CreateVpc createVpc244) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createVpc");
    }

    /**
     * Auto generated method signature
     *
                                 * @param replaceRouteTableAssociation246
     */

    public com.amazon.ec2.ReplaceRouteTableAssociationResponse replaceRouteTableAssociation(com.amazon.ec2.ReplaceRouteTableAssociation replaceRouteTableAssociation246) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#replaceRouteTableAssociation");
    }

    /**
     * Auto generated method signature
     *
                                 * @param associateRouteTable248
     */

    public com.amazon.ec2.AssociateRouteTableResponse associateRouteTable(com.amazon.ec2.AssociateRouteTable associateRouteTable248) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#associateRouteTable");
    }

    /**
     * Auto generated method signature
     *
                                 * @param detachInternetGateway250
     */

    public com.amazon.ec2.DetachInternetGatewayResponse detachInternetGateway(com.amazon.ec2.DetachInternetGateway detachInternetGateway250) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#detachInternetGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param purchaseReservedInstancesOffering252
     */

    public com.amazon.ec2.PurchaseReservedInstancesOfferingResponse purchaseReservedInstancesOffering(
        com.amazon.ec2.PurchaseReservedInstancesOffering purchaseReservedInstancesOffering252) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#purchaseReservedInstancesOffering");
    }

    /**
     * Auto generated method signature
     *
                                 * @param importVolume254
     */

    public com.amazon.ec2.ImportVolumeResponse importVolume(com.amazon.ec2.ImportVolume importVolume254) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#importVolume");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeExportTasks256
     */

    public com.amazon.ec2.DescribeExportTasksResponse describeExportTasks(com.amazon.ec2.DescribeExportTasks describeExportTasks256) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeExportTasks");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createInstanceExportTask258
     */

    public com.amazon.ec2.CreateInstanceExportTaskResponse createInstanceExportTask(com.amazon.ec2.CreateInstanceExportTask createInstanceExportTask258) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createInstanceExportTask");
    }

    /**
     * Auto generated method signature
     *
                                 * @param assignPrivateIpAddresses260
     */

    public com.amazon.ec2.AssignPrivateIpAddressesResponse assignPrivateIpAddresses(com.amazon.ec2.AssignPrivateIpAddresses assignPrivateIpAddresses260) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#assignPrivateIpAddresses");
    }

    /**
     * Auto generated method signature
     *
                                 * @param reportInstanceStatus262
     */

    public com.amazon.ec2.ReportInstanceStatusResponse reportInstanceStatus(com.amazon.ec2.ReportInstanceStatus reportInstanceStatus262) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#reportInstanceStatus");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeReservedInstancesOfferings264
     */

    public com.amazon.ec2.DescribeReservedInstancesOfferingsResponse describeReservedInstancesOfferings(
        com.amazon.ec2.DescribeReservedInstancesOfferings describeReservedInstancesOfferings264) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeReservedInstancesOfferings");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteVpnConnection266
     */

    public com.amazon.ec2.DeleteVpnConnectionResponse deleteVpnConnection(com.amazon.ec2.DeleteVpnConnection deleteVpnConnection266) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteVpnConnection");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteInternetGateway268
     */

    public com.amazon.ec2.DeleteInternetGatewayResponse deleteInternetGateway(com.amazon.ec2.DeleteInternetGateway deleteInternetGateway268) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteInternetGateway");
    }

    /**
     * Auto generated method signature
     *
                                 * @param deleteSpotDatafeedSubscription270
     */

    public com.amazon.ec2.DeleteSpotDatafeedSubscriptionResponse deleteSpotDatafeedSubscription(
        com.amazon.ec2.DeleteSpotDatafeedSubscription deleteSpotDatafeedSubscription270) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteSpotDatafeedSubscription");
    }

    /**
     * Auto generated method signature
     *
                                 * @param attachNetworkInterface272
     */

    public com.amazon.ec2.AttachNetworkInterfaceResponse attachNetworkInterface(com.amazon.ec2.AttachNetworkInterface attachNetworkInterface272) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#attachNetworkInterface");
    }

    /**
     * Auto generated method signature
     *
                                 * @param createNetworkInterface274
     */

    public com.amazon.ec2.CreateNetworkInterfaceResponse createNetworkInterface(com.amazon.ec2.CreateNetworkInterface createNetworkInterface274) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createNetworkInterface");
    }

    /**
     * Auto generated method signature
     *
                                 * @param revokeSecurityGroupEgress276
     */

    public com.amazon.ec2.RevokeSecurityGroupEgressResponse revokeSecurityGroupEgress(com.amazon.ec2.RevokeSecurityGroupEgress revokeSecurityGroupEgress276) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#revokeSecurityGroupEgress");
    }

    /**
     * Auto generated method signature
     *
                                 * @param monitorInstances278
     */

    public com.amazon.ec2.MonitorInstancesResponse monitorInstances(com.amazon.ec2.MonitorInstances monitorInstances278) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#monitorInstances");
    }

    /**
     * Auto generated method signature
     *
                                 * @param replaceRoute280
     */

    public com.amazon.ec2.ReplaceRouteResponse replaceRoute(com.amazon.ec2.ReplaceRoute replaceRoute280) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#replaceRoute");
    }

    /**
     * Auto generated method signature
     *
                                 * @param attachVolume282
     */

    public com.amazon.ec2.AttachVolumeResponse attachVolume(com.amazon.ec2.AttachVolume attachVolume282) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#attachVolume");
    }

    /**
     * Auto generated method signature
     *
                                 * @param getConsoleOutput284
     */

    public com.amazon.ec2.GetConsoleOutputResponse getConsoleOutput(com.amazon.ec2.GetConsoleOutput getConsoleOutput284) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getConsoleOutput");
    }

    /**
     * Auto generated method signature
     *
                                 * @param describeRegions286
     */

    public com.amazon.ec2.DescribeRegionsResponse describeRegions(com.amazon.ec2.DescribeRegions describeRegions286) {
        //TODO : fill this with the necessary business logic
        throw new java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#describeRegions");
    }

}
