// 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.

/**
 * AmazonS3Skeleton.java
 *
 * This file was auto-generated from WSDL
 * by the Apache Axis2 version: 1.5.1  Built on : Oct 19, 2009 (10:59:00 EDT)
 */
    package com.amazon.s3;
    /**
     *  AmazonS3Skeleton java skeleton for the axisService
     */
    public class AmazonS3Skeleton implements AmazonS3SkeletonInterface{
        
         
        /**
         * Auto generated method signature
         * 
                                     * @param getBucketLoggingStatus0
         */
        
                 public com.amazon.s3.GetBucketLoggingStatusResponse getBucketLoggingStatus
                  (
                  com.amazon.s3.GetBucketLoggingStatus getBucketLoggingStatus0
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getBucketLoggingStatus");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param copyObject2
         */
        
                 public com.amazon.s3.CopyObjectResponse copyObject
                  (
                  com.amazon.s3.CopyObject copyObject2
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#copyObject");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param getBucketAccessControlPolicy4
         */
        
                 public com.amazon.s3.GetBucketAccessControlPolicyResponse getBucketAccessControlPolicy
                  (
                  com.amazon.s3.GetBucketAccessControlPolicy getBucketAccessControlPolicy4
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getBucketAccessControlPolicy");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param listBucket6
         */
        
                 public com.amazon.s3.ListBucketResponse listBucket
                  (
                  com.amazon.s3.ListBucket listBucket6
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#listBucket");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param putObject8
         */
        
                 public com.amazon.s3.PutObjectResponse putObject
                  (
                  com.amazon.s3.PutObject putObject8
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#putObject");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param createBucket10
         */
        
                 public com.amazon.s3.CreateBucketResponse createBucket
                  (
                  com.amazon.s3.CreateBucket createBucket10
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#createBucket");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param listAllMyBuckets12
         */
        
                 public com.amazon.s3.ListAllMyBucketsResponse listAllMyBuckets
                  (
                  com.amazon.s3.ListAllMyBuckets listAllMyBuckets12
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#listAllMyBuckets");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param getObject14
         */
        
                 public com.amazon.s3.GetObjectResponse getObject
                  (
                  com.amazon.s3.GetObject getObject14
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getObject");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param deleteBucket16
         */
        
                 public com.amazon.s3.DeleteBucketResponse deleteBucket
                  (
                  com.amazon.s3.DeleteBucket deleteBucket16
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteBucket");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param setBucketLoggingStatus18
         */
        
                 public com.amazon.s3.SetBucketLoggingStatusResponse setBucketLoggingStatus
                  (
                  com.amazon.s3.SetBucketLoggingStatus setBucketLoggingStatus18
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#setBucketLoggingStatus");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param getObjectAccessControlPolicy20
         */
        
                 public com.amazon.s3.GetObjectAccessControlPolicyResponse getObjectAccessControlPolicy
                  (
                  com.amazon.s3.GetObjectAccessControlPolicy getObjectAccessControlPolicy20
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getObjectAccessControlPolicy");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param deleteObject22
         */
        
                 public com.amazon.s3.DeleteObjectResponse deleteObject
                  (
                  com.amazon.s3.DeleteObject deleteObject22
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#deleteObject");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param setBucketAccessControlPolicy24
         */
        
                 public com.amazon.s3.SetBucketAccessControlPolicyResponse setBucketAccessControlPolicy
                  (
                  com.amazon.s3.SetBucketAccessControlPolicy setBucketAccessControlPolicy24
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#setBucketAccessControlPolicy");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param setObjectAccessControlPolicy26
         */
        
                 public com.amazon.s3.SetObjectAccessControlPolicyResponse setObjectAccessControlPolicy
                  (
                  com.amazon.s3.SetObjectAccessControlPolicy setObjectAccessControlPolicy26
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#setObjectAccessControlPolicy");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param putObjectInline28
         */
        
                 public com.amazon.s3.PutObjectInlineResponse putObjectInline
                  (
                  com.amazon.s3.PutObjectInline putObjectInline28
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#putObjectInline");
        }
     
         
        /**
         * Auto generated method signature
         * 
                                     * @param getObjectExtended30
         */
        
                 public com.amazon.s3.GetObjectExtendedResponse getObjectExtended
                  (
                  com.amazon.s3.GetObjectExtended getObjectExtended30
                  )
            {
                //TODO : fill this with the necessary business logic
                throw new  java.lang.UnsupportedOperationException("Please implement " + this.getClass().getName() + "#getObjectExtended");
        }
     
    }
    