
/**
 * 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");
        }
     
    }
    