You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by xu...@apache.org on 2011/08/15 04:47:13 UTC

svn commit: r1157702 [2/3] - in /geronimo/bundles/trunk/axis2: pom.xml src/main/java/org/apache/axis2/jaxws/description/impl/EndpointInterfaceDescriptionImpl.java src/main/java/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java

Added: geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java
URL: http://svn.apache.org/viewvc/geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java?rev=1157702&view=auto
==============================================================================
--- geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java (added)
+++ geronimo/bundles/trunk/axis2/src/main/java/org/apache/axis2/jaxws/description/impl/OperationDescriptionImpl.java Mon Aug 15 02:47:13 2011
@@ -0,0 +1,2442 @@
+/*
+ * 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.
+ */
+
+
+package org.apache.axis2.jaxws.description.impl;
+
+import org.apache.axis2.AxisFault;
+import org.apache.axis2.addressing.wsdl.WSDL11ActionHelper;
+import org.apache.axis2.description.AxisMessage;
+import org.apache.axis2.description.AxisOperation;
+import org.apache.axis2.description.AxisOperationFactory;
+import org.apache.axis2.description.AxisService;
+import org.apache.axis2.description.Parameter;
+import org.apache.axis2.description.WSDL2Constants;
+import org.apache.axis2.java.security.AccessController;
+import org.apache.axis2.jaxws.ExceptionFactory;
+import org.apache.axis2.jaxws.description.AttachmentDescription;
+import org.apache.axis2.jaxws.description.EndpointDescriptionJava;
+import org.apache.axis2.jaxws.description.EndpointInterfaceDescription;
+import org.apache.axis2.jaxws.description.FaultDescription;
+import org.apache.axis2.jaxws.description.OperationDescription;
+import org.apache.axis2.jaxws.description.OperationDescriptionJava;
+import org.apache.axis2.jaxws.description.OperationDescriptionWSDL;
+import org.apache.axis2.jaxws.description.OperationRuntimeDescription;
+import org.apache.axis2.jaxws.description.ParameterDescription;
+import org.apache.axis2.jaxws.description.ParameterDescriptionJava;
+import org.apache.axis2.jaxws.description.builder.DescriptionBuilderComposite;
+import org.apache.axis2.jaxws.description.builder.FaultActionAnnot;
+import org.apache.axis2.jaxws.description.builder.MethodDescriptionComposite;
+import org.apache.axis2.jaxws.description.builder.OneWayAnnot;
+import org.apache.axis2.jaxws.description.builder.ParameterDescriptionComposite;
+import org.apache.axis2.jaxws.description.builder.converter.ConverterUtils;
+import org.apache.axis2.jaxws.i18n.Messages;
+import org.apache.axis2.jaxws.util.WSDL4JWrapper;
+import org.apache.axis2.wsdl.WSDLConstants;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.jws.Oneway;
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebParam.Mode;
+import javax.jws.WebResult;
+import javax.jws.soap.SOAPBinding;
+import javax.wsdl.Binding;
+import javax.wsdl.BindingInput;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.BindingOutput;
+import javax.wsdl.Definition;
+import javax.wsdl.extensions.AttributeExtensible;
+import javax.xml.namespace.QName;
+import javax.xml.ws.Action;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.FaultAction;
+import javax.xml.ws.RequestWrapper;
+import javax.xml.ws.Response;
+import javax.xml.ws.ResponseWrapper;
+import javax.xml.ws.WebFault;
+import java.io.File;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.net.URL;
+import java.security.PrivilegedAction;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+/** @see ../OperationDescription */
+// TODO: Axis2 does not support overloaded operations, although EndpointInterfaceDescription.addOperation() does support overloading
+//       of methods represented by OperationDescription classes.  However, the AxisOperation contained in an OperationDescription
+//       does NOT support overloaded methods.
+//
+//       While overloading is not supported by WS-I, it IS supported by JAX-WS (p11).
+//       Note that this requires support in Axis2; currently WSDL11ToAxisServiceBuilder.populateOperations does not
+//       support overloaded methods in the WSDL; the operations are stored on AxisService as children in a HashMap with the wsdl
+//       operation name as the key.
+
+class OperationDescriptionImpl
+        implements OperationDescription, OperationDescriptionJava, OperationDescriptionWSDL {
+    private final EndpointInterfaceDescription parentEndpointInterfaceDescription;
+    private final AxisOperation axisOperation;
+    private final QName operationQName;
+    private Method seiMethod;
+    private final MethodDescriptionComposite methodComposite;
+    private ParameterDescription[] parameterDescriptions;
+    private FaultDescription[] faultDescriptions;
+    private static final Log log = LogFactory.getLog(OperationDescriptionImpl.class);
+    // ===========================================
+    // ANNOTATION related information
+    // ===========================================
+
+    // ANNOTATION: @Oneway
+    private Oneway onewayAnnotation;
+    private Boolean onewayIsOneway;
+
+    // ANNOTATION: @XmlList
+    private boolean isListType = false;
+
+    // ANNOTATION: @RequestWrapper
+    private RequestWrapper requestWrapperAnnotation;
+    private String requestWrapperTargetNamespace;
+    private String requestWrapperLocalName;
+    private String requestWrapperClassName;
+    private String requestWrapperPartName;
+    // ANNOTATION: @ResponseWrapper
+    private ResponseWrapper responseWrapperAnnotation;
+    private String responseWrapperLocalName;
+    private String responseWrapperTargetNamespace;
+    private String responseWrapperClassName;
+    private String responseWrapperPartName;
+    // ANNOTATION: @Action
+    private Action actionAnnotation;
+
+    // ANNOTATION: @SOAPBinding
+    // Note this is the Method-level annotation.  See EndpointInterfaceDescription for the Type-level annotation
+    // Also note this annotation is only allowed on methods if SOAPBinding.Style is DOCUMENT and if the method-level
+    // annotation is absent, the behavior defined on the Type is used.
+    // per JSR-181 MR Sec 4.7 "Annotation: javax.jws.soap.SOAPBinding" pg 28
+    private SOAPBinding soapBindingAnnotation;
+    private javax.jws.soap.SOAPBinding.Style soapBindingStyle;
+    public static final javax.jws.soap.SOAPBinding.Style SoapBinding_Style_VALID =
+            javax.jws.soap.SOAPBinding.Style.DOCUMENT;
+    private javax.jws.soap.SOAPBinding.Use soapBindingUse;
+    // Default value per JSR-181 MR Sec 4.7 "Annotation: javax.jws.soap.SOAPBinding" pg 28
+    public static final javax.jws.soap.SOAPBinding.Use SOAPBinding_Use_DEFAULT =
+            javax.jws.soap.SOAPBinding.Use.LITERAL;
+    private javax.jws.soap.SOAPBinding.ParameterStyle soapBindingParameterStyle;
+    // Default value per JSR-181 MR Sec 4.7 "Annotation: javax.jws.soap.SOAPBinding" pg 28
+    public static final javax.jws.soap.SOAPBinding.ParameterStyle SOAPBinding_ParameterStyle_DEFAULT =
+            javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
+
+    // ANNOTATION: @WebMethod
+    private WebMethod webMethodAnnotation;
+    private String webMethodOperationName;
+    // Default value per JSR-181 MR Sec 4.2, pg 17
+    public static final String WebMethod_Action_DEFAULT = "";
+    private String webMethodAction;
+    // Default value per JSR-181 MR sec 4.2, pg 17
+    public static final Boolean WebMethod_Exclude_DEFAULT = Boolean.FALSE;
+    private Boolean webMethodExclude;
+
+    // ANNOTATION: @WebParam
+    private String[] webParamNames;
+    private Mode[] webParamMode;
+    private String[] webParamTargetNamespace;
+
+
+    // ANNOTATION: @WebResult
+    private WebResult webResultAnnotation;
+    private String webResultName;
+    private String webResultPartName;
+    // Default value per JSR-181 MR Sec 4.5.1, pg 23
+    public static final String WebResult_TargetNamespace_DEFAULT = "";
+    private String webResultTargetNamespace;
+    // Default value per JSR-181 MR sec 4.5, pg 24
+    public static final Boolean WebResult_Header_DEFAULT = Boolean.FALSE;
+    private Boolean webResultHeader;
+    
+    //  Web Result Attachment Description information
+    private boolean             _setAttachmentDesc = false;
+    private AttachmentDescription attachmentDesc = null;
+    
+    private boolean hasRequestSwaRefAttachments = false;
+    private boolean hasResponseSwaRefAttachments = false;
+    private Map<String, AttachmentDescription> partAttachmentMap;
+    
+    private Method serviceImplMethod;
+    private boolean serviceImplMethodFound = false;
+    // For JAX-WS client async methods, this is the corresponding Sync method; for everything else,
+    // this is "this".
+    private OperationDescription syncOperationDescription = null;
+    // RUNTIME INFORMATION
+    Map<String, OperationRuntimeDescription> runtimeDescMap =
+            Collections.synchronizedMap(new HashMap<String, OperationRuntimeDescription>());
+    // Cache the actual Class of the type being returned. 
+    private Class resultActualTypeClazz;
+
+    OperationDescriptionImpl(Method method, EndpointInterfaceDescription parent) {
+        parentEndpointInterfaceDescription = parent;
+        methodComposite = null;
+        partAttachmentMap = new HashMap<String, AttachmentDescription>();
+        setSEIMethod(method);
+		
+        // The operationQName is intentionally unqualified to be consistent with the remaining parts of the system. 
+        // Using a qualified name will cause breakage.
+        // Don't do --> this.operationQName = new QName(parent.getTargetNamespace(), getOperationName());
+        this.operationQName = new QName("", getOperationName());
+        if (getEndpointInterfaceDescription().getEndpointDescription() != null) {
+            if (!getEndpointInterfaceDescription().getEndpointDescription().getServiceDescription().isServerSide()) {
+                axisOperation = createClientAxisOperation();
+            } else {
+                axisOperation = null;
+            }
+        } else {
+            axisOperation = null;
+        }
+        if(this.axisOperation != null) {
+            try {
+                this.axisOperation.addParameter(new Parameter(OperationDescription.AXIS_OPERATION_PARAMETER,
+                                                         this));  
+            }
+            catch(AxisFault af) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("operationDescriptionErr1"));
+            }
+        }
+        buildAttachmentInformation();
+    }
+
+    OperationDescriptionImpl(AxisOperation operation, EndpointInterfaceDescription parent) {
+        parentEndpointInterfaceDescription = parent;
+        partAttachmentMap = new HashMap<String, AttachmentDescription>();
+        axisOperation = operation;
+        methodComposite = null;
+        if(this.axisOperation != null) {
+            this.operationQName = axisOperation.getName();
+            try {
+                this.axisOperation.addParameter(new Parameter(OperationDescription.AXIS_OPERATION_PARAMETER,
+                                                         this));  
+            }
+            catch(AxisFault af) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("operationDescriptionErr1"));
+            }
+        } else {
+            operationQName = null;
+        }
+        buildAttachmentInformation();
+    }
+
+    OperationDescriptionImpl(MethodDescriptionComposite mdc,
+                             EndpointInterfaceDescription parent,
+                             AxisOperation axisOperation) {
+
+        parentEndpointInterfaceDescription = parent;
+        partAttachmentMap = new HashMap<String, AttachmentDescription>();
+        methodComposite = mdc;
+        // The operationQName is intentionally unqualified to be consistent with the remaining parts of the system. 
+        // Using a qualified name will cause breakage.
+        // Don't do --> this.operationQName = new QName(parent.getTargetNamespace(), getOperationName());
+        this.operationQName = new QName("", getOperationName());
+
+        webMethodAnnotation = methodComposite.getWebMethodAnnot();
+
+        parameterDescriptions = createParameterDescriptions();
+        faultDescriptions = createFaultDescriptions();
+        isListType = mdc.isListType();
+        buildAttachmentInformation();
+
+        //If an AxisOperation was already created for us by populateService then just use that one
+        //Otherwise, create it
+        if (axisOperation != null) {
+            this.axisOperation = axisOperation;
+        } else {
+            this.axisOperation = createAxisOperation();
+        }
+        
+        if(this.axisOperation != null) {
+            try {
+                this.axisOperation.addParameter(new Parameter(OperationDescription.AXIS_OPERATION_PARAMETER,
+                                                         this));  
+            }
+            catch(AxisFault af) {
+                throw ExceptionFactory.makeWebServiceException(Messages.getMessage("operationDescriptionErr1"));
+            }
+        }
+        
+        // Register understood headers on axisOperation
+        registerMustUnderstandHeaders();
+    }
+
+    /**
+     * Create an AxisOperation for this Operation.  Note that the ParameterDescriptions must
+     * be created before calling this method since, for a DOC/LIT/BARE (aka UNWRAPPED) message, the 
+     * ParamaterDescription is used to setup the AxisMessage correctly for use in SOAP Body-based
+     * dispatching on incoming DOC/LIT/BARE messages.
+     */
+    private AxisOperation createClientAxisOperation() {
+        AxisOperation newAxisOperation = null;
+        try {
+            if (isOneWay()) {
+                newAxisOperation =
+                        AxisOperationFactory.getOperationDescription(WSDL2Constants.MEP_URI_OUT_ONLY);
+            } else {
+                newAxisOperation =
+                        AxisOperationFactory.getOperationDescription(WSDL2Constants.MEP_URI_OUT_IN);
+            }
+            //REVIEW: There are several other MEP's, such as: OUT_ONLY, IN_OPTIONAL_OUT, OUT_IN, OUT_OPTIONAL_IN, ROBUST_OUT_ONLY,
+            //                                              ROBUST_IN_ONLY
+            //      Determine how these MEP's should be handled, if at all
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("clientAxisOprErr"),e);
+        }
+
+        newAxisOperation.setName(determineOperationQName(seiMethod));
+        newAxisOperation.setSoapAction(this.getAction());
+        
+        //*************************************************************************************
+        //NOTE: assumption here is that all info. need to generate the actions will have to come
+        //      from annotations (or default values)
+        //*************************************************************************************
+        
+        String messageExchangePattern = newAxisOperation.getMessageExchangePattern();
+        String operationName = newAxisOperation.getName().getLocalPart();
+        String targetNS = getEndpointInterfaceDescriptionImpl().getTargetNamespace();        
+        String portTypeName = getEndpointInterfaceDescriptionImpl().getPortType().getLocalPart();
+         
+        //We don't have a name at this point, shouldn't matter if we have the MEP.
+        //On the client the input and output actions are reversed.
+        String inputName = null;
+        String inputAction = getOutputAction();
+
+        //If we still don't have an action then fall back to the Default Action Pattern.
+        if (inputAction == null || inputAction.length() == 0) {
+            inputAction =
+                WSDL11ActionHelper.getInputActionFromStringInformation( messageExchangePattern, 
+                                                                        targetNS, 
+                                                                        portTypeName, 
+                                                                        operationName, 
+                                                                        inputName);
+        }
+                
+        ArrayList inputActions = new ArrayList();
+        inputActions.add(inputAction);
+        newAxisOperation.setWsamappingList(inputActions);
+        
+        //Map the action to the operation on the actual axisService
+        //TODO: Determine whether this should be done at a higher level in the 
+        //      description hierarchy
+        getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl().
+            getAxisService().mapActionToOperation(inputAction, newAxisOperation);        
+        
+        //set the OUTPUT ACTION
+
+        //We don't have a name at this point, shouldn't matter if we have the MEP
+        //On the client the input and output actions are reversed.
+        String outputName = null;
+        String outputAction = getInputAction();
+
+        if (outputAction == null || outputAction.length() == 0) {
+            outputAction =
+                WSDL11ActionHelper.getOutputActionFromStringInformation( messageExchangePattern, 
+                                                                         targetNS, 
+                                                                         portTypeName, 
+                                                                         operationName, 
+                                                                         outputName);
+        }
+        
+        newAxisOperation.setOutputAction(outputAction);
+
+        setFaultActions(newAxisOperation, operationName, targetNS, portTypeName);
+
+        getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl().
+            getAxisService().addOperation(newAxisOperation);
+        
+        return newAxisOperation;
+    }
+    
+    /**
+     * Create an AxisOperation for this Operation.  Note that the ParameterDescriptions must
+     * be created before calling this method since, for a DOC/LIT/BARE (aka UNWRAPPED) message, the 
+     * ParamaterDescription is used to setup the AxisMessage correctly for use in SOAP Body-based
+     * dispatching on incoming DOC/LIT/BARE messages.
+     */
+    private AxisOperation createAxisOperation() {
+        AxisOperation newAxisOperation = null;
+        try {
+            if (isOneWay()) {
+                newAxisOperation = AxisOperationFactory
+                        .getOperationDescription(WSDL2Constants.MEP_URI_IN_ONLY);
+            } else {
+                newAxisOperation =
+                        AxisOperationFactory.getOperationDescription(WSDL2Constants.MEP_URI_IN_OUT);
+            }
+            //TODO: There are several other MEP's, such as: OUT_ONLY, IN_OPTIONAL_OUT, OUT_IN, OUT_OPTIONAL_IN, ROBUST_OUT_ONLY,
+            //                                              ROBUST_IN_ONLY
+            //      Determine how these MEP's should be handled, if at all
+        } catch (Exception e) {
+            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("clientAxisOprErr"), e);
+        }
+
+        newAxisOperation.setName(determineOperationQName(getEndpointInterfaceDescriptionImpl(),this.methodComposite));
+        newAxisOperation.setSoapAction(this.getAction());
+
+        //*************************************************************************************
+        //NOTE: assumption here is that all info. need to generate the actions will have to come
+        //      from annotations (or default values)
+        //*************************************************************************************
+        
+        String messageExchangePattern = newAxisOperation.getMessageExchangePattern();
+        String operationName = newAxisOperation.getName().getLocalPart();
+        String targetNS = getEndpointInterfaceDescriptionImpl().getTargetNamespace();        
+        String portTypeName = getEndpointInterfaceDescriptionImpl().getPortType().getLocalPart();
+         
+        //We don't have a name at this point, shouldn't matter if we have the MEP
+        String inputName = null;
+        String inputAction = getInputAction();
+        
+        //If we don't have an action then fall back to the Default Action Pattern.
+        if (inputAction == null || inputAction.length() == 0) {
+            inputAction =
+                WSDL11ActionHelper.getInputActionFromStringInformation(messageExchangePattern, 
+                                                                       targetNS, 
+                                                                       portTypeName, 
+                                                                       operationName, 
+                                                                       inputName);
+        }
+        
+        ArrayList inputActions = new ArrayList();
+        inputActions.add(inputAction);
+        newAxisOperation.setWsamappingList(inputActions);
+        
+        //Map the action to the operation on the actual axisService
+        //TODO: Determine whether this should be done at a higher level in the 
+        //      description hierarchy
+        getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl().
+            getAxisService().mapActionToOperation(inputAction, newAxisOperation);
+        
+        //set the OUTPUT ACTION
+
+        //We don't have a name at this point, shouldn't matter if we have the MEP
+        String outputName = null;
+        String outputAction = getOutputAction();
+        
+        //If we don't have an action then fall back to the Default Action Pattern.
+        if (outputAction == null || outputAction.length() == 0) {
+            outputAction =
+                WSDL11ActionHelper.getOutputActionFromStringInformation(messageExchangePattern,
+                                                                        targetNS, 
+                                                                        portTypeName, 
+                                                                        operationName, 
+                                                                        outputName);
+        }
+        
+        newAxisOperation.setOutputAction(outputAction);
+        
+        //Set the FAULT ACTION
+        setFaultActions(newAxisOperation, operationName, targetNS, portTypeName);
+
+        // If this is a DOC/LIT/BARE operation, then set the QName of the input AxisMessage to the 
+        // part for the first IN or IN/OUT non-header parameter.  If there are no parameters, then don't set
+        // anything.  The AxisMessage name is used to do SOAP-body based routing of DOC/LIT/BARE
+        // incoming messages.
+        if (getSoapBindingStyle() == javax.jws.soap.SOAPBinding.Style.DOCUMENT
+                && getSoapBindingUse() == javax.jws.soap.SOAPBinding.Use.LITERAL
+                && getSoapBindingParameterStyle() == javax.jws.soap.SOAPBinding.ParameterStyle.BARE)
+        {
+            ParameterDescription[] paramDescs = getParameterDescriptions();
+            if (paramDescs != null && paramDescs.length > 0) {
+                for (ParameterDescription paramDesc : paramDescs) {
+                    WebParam.Mode paramMode = paramDesc.getMode();
+                    if (!paramDesc.isHeader()
+                            && (paramMode == WebParam.Mode.IN || paramMode == WebParam.Mode.INOUT))
+                    {
+                        // We've found the first IN or INOUT non-header parameter, so set the AxisMessage
+                        // QName based on this parameter then break out of the loop.
+                        AxisMessage axisMessage =
+                                newAxisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+                        String elementName = paramDesc.getParameterName();
+                        String partNamespace = paramDesc.getTargetNamespace();
+                        if (log.isDebugEnabled()) {
+                            log.debug("Setting up annotation based Doc/Lit/Bare operation: " +
+                                    newAxisOperation.getName()
+                                    + "; axisMessage: " + axisMessage + "; name: "
+                                    + elementName + "; partTNS: " + partNamespace);
+                        }
+                        if (axisMessage == null) {
+                            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("createAxisOprErr1"));
+                        } else if (DescriptionUtils.isEmpty(partNamespace)) {
+                            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("createAxisOprErr2"));
+                        } else if (DescriptionUtils.isEmpty(elementName)) {
+                            throw ExceptionFactory.makeWebServiceException(Messages.getMessage("createAxisOprErr3"));
+                        } else {
+                            QName partQName = new QName(partNamespace, elementName);
+                            if(log.isDebugEnabled()) {
+                                log.debug("Setting AxisMessage element QName for bare mapping: " +
+                                        partQName);
+                            }
+                            axisMessage.setElementQName(partQName);
+                            
+                            getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl()
+                        		.getAxisService()
+                        			.addMessageElementQNameToOperationMapping(partQName, newAxisOperation);
+                        }
+                        break;
+                    }
+                }
+            } else {
+                // There are no parameters for this Doc/Lit/Bare operation.  That means the inbound soap:Body will
+                // be empty, so when asking the Body for the first element QName for routing purposes, a null will 
+                // be returned.  By mapping a null key to this operation here, it will be the one found for the null
+                // element during routing.
+                getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl().getAxisService()
+                    .addMessageElementQNameToOperationMapping(null, newAxisOperation);
+            }
+        }
+        return newAxisOperation;
+    }
+
+    private void setFaultActions(AxisOperation newAxisOperation,
+                                 String operationName,
+                                 String targetNS,
+                                 String portTypeName) {
+        // Walk the fault information
+        FaultDescription[] faultDescs = getFaultDescriptions();
+        
+        //Generate fault actions according to the Default Action Pattern.
+        if (faultDescs != null) {
+            for (FaultDescription faultDesc : faultDescs) {
+        
+                AxisMessage faultMessage = new AxisMessage();
+                String faultName = faultDesc.getName();
+                
+                if (faultName == null || faultName.equals("")) {
+                    faultName = faultDesc.getExceptionClassName();
+                    // Remove package name to get just class name
+                    faultName = faultName.substring((faultName.lastIndexOf('.'))+1);
+                }
+                
+                faultMessage.setName(faultName);
+                if (log.isDebugEnabled()) {
+                    log.debug("Set faultName = "+faultName+" for faultMessage = "+faultMessage+" and faultDesc = "+faultDesc);
+                }
+                
+                String faultAction = 
+                        WSDL11ActionHelper.getFaultActionFromStringInformation( targetNS, 
+                                        portTypeName, 
+                                        operationName, 
+                                        faultMessage.getName());
+
+                if (log.isDebugEnabled()) {
+                    log.debug("Default faultAction = "+faultAction);
+                }
+                
+                newAxisOperation.addFaultAction(faultDesc.getExceptionClassName(),  faultAction);
+                newAxisOperation.setFaultMessages(faultMessage);
+            }
+        }
+        
+        //Override the fault actions based on any FaultAction annotations that are defined.
+        FaultAction[] faultActions = getFaultActions();
+        
+        if (faultActions != null) {
+            for (FaultAction faultAction : faultActions) {
+                
+                String className = null;
+                
+                if(faultAction instanceof FaultActionAnnot
+                        &&
+                        ((FaultActionAnnot) faultAction).classNameString() != null) {
+                    className = ((FaultActionAnnot) faultAction).classNameString();
+                }
+                else if(faultAction.className() != null) {
+                    className = faultAction.className().getName();
+                }
+                
+                if(className != null) {
+                    if(log.isDebugEnabled()) {
+                        log.debug("Looking for FaultDescription for class: " + className + 
+                                  " from @FaultAction annotation");
+                    }
+                    FaultDescription faultDesc = resolveFaultByExceptionName(className);
+                    if (faultDesc != null)  {
+                        String faultActionString = faultAction.value();
+                        if (log.isDebugEnabled()) {
+                            log.debug("faultAction value = "+faultActionString);
+                        }
+
+                        if (faultActionString != null && !faultActionString.equals("")) {
+                            newAxisOperation.addFaultAction(className, faultActionString);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds the AxisOperation corresponding to this OperationDescription to the AxisService if it
+     * isn't already there. It also addes the AxisOperation to any other routing mechanisms for
+     * that AxisService: - For Doc/Lit/Bare operations it is added to the
+     * MessageElementQNameToOperationMapping
+     *
+     * @param axisService
+     */
+    void addToAxisService(AxisService axisService) {
+        AxisOperation newAxisOperation = getAxisOperation();
+        QName axisOpQName = newAxisOperation.getName();
+        // See if this operation is already added to the AxisService.  Note that we need to check the 
+        // children of the service rather than using the getOperation(axisOpQName) method.  The reason is 
+        // that method checks the alias table in addition to the children, and it is possible at this point
+        // for an operation to have just been added to the alias table but not yet as a child.  It is this method
+        // that will add that newly-created operation to the service.
+        AxisOperation existingAxisOperation = (AxisOperation) axisService.getChild(axisOpQName);
+
+        if (existingAxisOperation == null) {
+            axisService.addOperation(newAxisOperation);
+            // For a Doc/Lit/Bare operation, we also need to add the element mapping
+        }
+        if (getSoapBindingStyle() == javax.jws.soap.SOAPBinding.Style.DOCUMENT
+                && getSoapBindingUse() == javax.jws.soap.SOAPBinding.Use.LITERAL
+                && getSoapBindingParameterStyle() == javax.jws.soap.SOAPBinding.ParameterStyle
+                .BARE) {
+            AxisMessage axisMessage =
+                    null;
+            if (existingAxisOperation!=null) {
+                axisMessage = existingAxisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+            } else {
+                axisMessage = newAxisOperation.getMessage(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
+            }
+            if (axisMessage != null) {
+                QName elementQName = axisMessage.getElementQName();
+                if (!DescriptionUtils.isEmpty(elementQName) && 
+                    axisService.getOperationByMessageElementQName(elementQName) == null) {
+                    axisService.addMessageElementQNameToOperationMapping(elementQName,
+                            newAxisOperation);
+                }
+            }
+        }
+    }
+
+    void setSEIMethod(Method method) {
+        if (seiMethod != null) {
+        	throw ExceptionFactory.makeWebServiceException(
+        			new UnsupportedOperationException(Messages.getMessage("seiMethodErr")));
+        } else {
+            // Reset any cached state (see AXIS2-5115)
+            webMethodAnnotation = null;
+            webMethodOperationName = null;
+            webMethodAction = null;
+            webMethodExclude = null;
+            requestWrapperAnnotation = null;
+            requestWrapperLocalName = null;
+            requestWrapperTargetNamespace = null;
+            requestWrapperClassName = null;
+            requestWrapperPartName = null;
+            responseWrapperAnnotation = null;
+            responseWrapperLocalName = null;
+            responseWrapperTargetNamespace = null;
+            responseWrapperClassName = null;
+            responseWrapperPartName = null;
+            webParamNames = null;
+            webParamTargetNamespace = null;
+            webParamMode = null;
+            webResultAnnotation = null;
+            webResultName = null;
+            webResultPartName = null;
+            webResultTargetNamespace = null;
+            webResultHeader = null;
+            soapBindingAnnotation = null;
+            soapBindingStyle = null;
+            soapBindingUse = null;
+            soapBindingParameterStyle = null;
+            actionAnnotation = null;
+            onewayAnnotation = null;
+            onewayIsOneway = null;
+            resultActualTypeClazz = null;
+
+            seiMethod = method;
+            webMethodAnnotation = (WebMethod)
+                getAnnotation(seiMethod, WebMethod.class);
+            parameterDescriptions = createParameterDescriptions();
+            faultDescriptions = createFaultDescriptions();
+            isListType = ConverterUtils.hasXmlListAnnotation(seiMethod.getAnnotations());
+        }
+        // Register understood headers on axisOperation
+        registerMustUnderstandHeaders();
+    }
+
+    public EndpointInterfaceDescription getEndpointInterfaceDescription() {
+        return parentEndpointInterfaceDescription;
+    }
+
+    public EndpointInterfaceDescriptionImpl getEndpointInterfaceDescriptionImpl() {
+        return (EndpointInterfaceDescriptionImpl)parentEndpointInterfaceDescription;
+    }
+
+    public AxisOperation getAxisOperation() {
+        // Note that only the sync operations, and not the JAX-WS async client versions of an 
+        // operation, will have an AxisOperation associated with it.  For those async operations, 
+        // get the AxisOperation associated with the sync method and return that.
+        if (axisOperation == null) {
+            OperationDescription opDesc = getSyncOperation();
+            if (opDesc != null && opDesc != this) {
+                return getSyncOperation().getAxisOperation();
+            }
+        } 
+        
+        return axisOperation;
+    }
+
+    public QName getName() {
+        return operationQName;
+    }
+
+    // Java-related getters
+    public String getJavaMethodName() {
+        String returnString = null;
+
+        if (!isDBC()) {
+            if (seiMethod != null) {
+                returnString = seiMethod.getName();
+            }
+        } else {
+            if (methodComposite != null) {
+                returnString = methodComposite.getMethodName();
+            }
+        }
+
+        return returnString;
+    }
+
+    public String getJavaDeclaringClassName() {
+        if (!isDBC() && seiMethod != null) {
+            Class clazz = seiMethod.getDeclaringClass();
+            return clazz.getCanonicalName();
+        } else if (methodComposite != null) {
+            return methodComposite.getDeclaringClass();
+        }
+        return null;
+    }
+
+    public String[] getJavaParameters() {
+
+        ArrayList<String> returnParameters = new ArrayList<String>();
+
+        if (!isDBC()) {
+            if (seiMethod != null) {
+                Class[] paramaters = seiMethod.getParameterTypes();
+                for (Class param : paramaters) {
+                    returnParameters.add(param.getName());
+                }
+            }
+
+        } else {
+            if (methodComposite != null) {
+
+                Iterator<ParameterDescriptionComposite> iter =
+                        methodComposite.getParameterDescriptionCompositeList().iterator();
+                while (iter.hasNext()) {
+                    returnParameters.add(iter.next().getParameterType());
+                }
+            }
+        }
+
+        // TODO: This is different than the rest, which return null instead of an empty array
+        return returnParameters.toArray(new String[0]);
+    }
+
+    /**
+     * Note this will return NULL unless the operation was built via introspection on the SEI. In
+     * other words, it will return null if the operation was built with WSDL.
+     *
+     * @return
+     */
+    public Method getSEIMethod() {
+        return seiMethod;
+    }
+
+    MethodDescriptionComposite getMethodDescriptionComposite() {
+        return methodComposite;
+    }
+
+    private boolean isWrappedParameters() {
+        return getSoapBindingParameterStyle() == javax.jws.soap.SOAPBinding.ParameterStyle.WRAPPED;
+    }
+
+    private ParameterDescription[] createParameterDescriptions() {
+
+        ArrayList<ParameterDescription> buildParameterList = new ArrayList<ParameterDescription>();
+
+        if (!isDBC()) {
+            Class[] parameters = seiMethod.getParameterTypes();
+            Type[] paramaterTypes = seiMethod.getGenericParameterTypes();
+            Annotation[][] annotations = seiMethod.getParameterAnnotations();
+
+            for (int i = 0; i < parameters.length; i++) {
+                ParameterDescription paramDesc = new ParameterDescriptionImpl(i, parameters[i],
+                                                                              paramaterTypes[i],
+                                                                              annotations[i], this);
+                buildParameterList.add(paramDesc);
+            }
+
+        } else {
+
+            for (int i = 0; i < methodComposite.getParameterDescriptionCompositeList().size(); i++)
+            {
+                ParameterDescription paramDesc =
+                        new ParameterDescriptionImpl(i,
+                                                     methodComposite.getParameterDescriptionComposite(
+                                                             i),
+                                                     this);
+                buildParameterList.add(paramDesc);
+            }
+        }
+
+        return buildParameterList.toArray(new ParameterDescription[buildParameterList.size()]);
+
+    }
+
+    private FaultDescription[] createFaultDescriptions() {
+
+        ArrayList<FaultDescription> buildFaultList = new ArrayList<FaultDescription>();
+
+        if (!isDBC()) {
+            // get exceptions this method "throws"
+            Class[] webFaultClasses = seiMethod.getExceptionTypes();
+
+            for (Class wfClass : webFaultClasses) {
+                // according to JAXWS 3.7, the @WebFault annotation is only used for customizations,
+                // so we'll add all declared exceptions
+                WebFault wfanno = null;
+                for (Annotation anno : wfClass.getAnnotations()) {
+                    if (anno.annotationType() == WebFault.class) {
+                        wfanno = (WebFault)anno;
+                    }
+                }
+                buildFaultList.add(new FaultDescriptionImpl(wfClass, wfanno, this));
+            }
+        } else {
+            // TODO do I care about methodComposite like the paramDescription does?
+            //Call FaultDescriptionImpl for all non-generic exceptions...Need to check a
+            // a couple of things
+            // 1. If this is a generic exception, ignore it
+            // 2. If this is not a generic exception, then find it in the DBC Map
+            //       If not found in map, then throw not found exception
+            //3. Pass the validated WebFault dbc and possibly the classImpl dbc to FaultDescription
+            //4. Possibly set AxisOperation.setFaultMessages array...or something like that
+
+            String[] webFaultClassNames = methodComposite.getExceptions();
+
+            HashMap<String, DescriptionBuilderComposite> dbcMap =
+                    getEndpointInterfaceDescriptionImpl().getEndpointDescriptionImpl()
+                            .getServiceDescriptionImpl().getDBCMap();
+
+            if (webFaultClassNames != null) {
+                for (String wfClassName : webFaultClassNames) {
+                    //	Try to find this exception class in the dbc list. If we can't find it
+                    //  then just assume that its a generic exception.
+
+                    DescriptionBuilderComposite faultDBC = dbcMap.get(wfClassName);
+
+                    if (faultDBC != null) {
+                        // JAXWS 3.7 does not require @WebFault annotation
+                        // We found a valid exception composite thats annotated
+                        buildFaultList.add(new FaultDescriptionImpl(faultDBC, this));
+                    }
+
+                }
+            }
+        }
+
+        return buildFaultList.toArray(new FaultDescription[0]);
+    }
+
+    // =====================================
+    // ANNOTATION: WebMethod
+    // =====================================
+    public WebMethod getAnnoWebMethod() {
+        if (webMethodAnnotation == null) {
+            if (isDBC() && methodComposite != null) {
+                webMethodAnnotation = methodComposite.getWebMethodAnnot();
+            } else if (!isDBC() && seiMethod != null) {
+                webMethodAnnotation = (WebMethod) getAnnotation(seiMethod, WebMethod.class);
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get WebMethod annotation");
+                }
+            }
+        }
+        return webMethodAnnotation;
+    }
+
+    static QName determineOperationQName(Method javaMethod) {
+        if (log.isDebugEnabled())
+        {
+          log.debug("Operation QName determined to be: "+new QName(determineOperationName(javaMethod)));
+        }
+
+        return new QName(determineOperationName(javaMethod));
+    }
+
+    //According to section 4.1.1 of JSR181, the Operation should inherit
+    //the target namespace from the @WebService annotation on the SEI or
+    //service implementation bean.  However, changing the above method
+    //currently causes problems with the clients and leaving it as is
+    //does not seem to have produced any issues (as of yet.)
+    public static QName determineOperationQName(EndpointInterfaceDescription eid, MethodDescriptionComposite mdc) {
+        if (log.isDebugEnabled())
+        {
+          log.debug("Operation QName determined to be: "+((eid!= null)?new QName(eid.getTargetNamespace(), determineOperationName(mdc)):new QName(determineOperationName(mdc))));
+        }
+        return ((eid!= null)?new QName(eid.getTargetNamespace(), determineOperationName(mdc)):new QName(determineOperationName(mdc)));
+    }
+    
+    private static String determineOperationName(Method javaMethod) {
+
+        String operationName = null;
+        if (javaMethod == null) {
+            return null;
+        }
+
+        WebMethod wmAnnotation = (WebMethod) getAnnotation(javaMethod,WebMethod.class);
+        // Per JSR-181 MR Sec 4.2 "Annotation: javax.jws.WebMethod" pg 17,
+        // if @WebMethod specifies and operation name, use that.  Otherwise
+        // default is the Java method name
+        if (wmAnnotation != null && !DescriptionUtils.isEmpty(wmAnnotation.operationName())) {
+            operationName = wmAnnotation.operationName();
+        } else {
+            operationName = javaMethod.getName();
+        }
+
+        return operationName;
+    }
+
+    //TODO: For now, we are overriding the above method only because it is static, these should
+    //be combined at some point
+    private static String determineOperationName(MethodDescriptionComposite mdc) {
+        String operationName = null;
+
+        if (mdc == null) {
+            return null;
+        }
+        WebMethod wmAnnotation = mdc.getWebMethodAnnot();
+        if (wmAnnotation != null && !DescriptionUtils.isEmpty(wmAnnotation.operationName())) {
+            operationName = wmAnnotation.operationName();
+        } else {
+            operationName = mdc.getMethodName();
+        }
+
+        return operationName;
+    }
+
+    public String getOperationName() {
+        return getAnnoWebMethodOperationName();
+    }
+
+    public String getAnnoWebMethodOperationName() {
+        if (webMethodOperationName == null) {
+            if (!isDBC() && seiMethod != null) {
+                webMethodOperationName = determineOperationName(seiMethod);
+            } else if (methodComposite != null) {
+                webMethodOperationName = determineOperationName(methodComposite);
+            }
+        }
+        return webMethodOperationName;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.OperationDescription#getSyncOperation()
+     */
+    public OperationDescription getSyncOperation() {
+        if (log.isDebugEnabled()) {
+            log.debug("Current OperationDescription Web Method annotation \"operation\" name: " 
+                    + getOperationName());
+            log.debug("Current OperationDescription java method name: " + getJavaMethodName());
+        }
+        if (syncOperationDescription != null) {
+            // No need to do anything; the sync operation has already been set and will be
+            // returned below
+        } else if (!isJAXWSAsyncClientMethod()) {
+            // The current OpDesc is not an async operation.  Cache it, then return it below.
+            syncOperationDescription = this;
+        } else {
+            // We haven't found a sync opdesc for this operation yet, so try again.  See the 
+            // comments in the interface declaration for this method on why this might occur.
+            OperationDescription opDesc = null;
+            
+            String webMethodAnnoName = getOperationName();
+            String javaMethodName = getJavaMethodName();
+            if (webMethodAnnoName != null && webMethodAnnoName.length() > 0 &&
+                    webMethodAnnoName != javaMethodName) {
+                EndpointInterfaceDescription eid = getEndpointInterfaceDescription();
+                if (eid != null) {
+                    //searching for operationDescription of synchronous operation.
+                    OperationDescription[] allOperations = eid.getOperations();
+                    // Find a method that has a matching annotation but is not 
+                    // an asynchronous operation.
+                    for (OperationDescription operation : allOperations) {
+                        if (webMethodAnnoName.equals(operation.getOperationName()) &&
+                                !operation.isJAXWSAsyncClientMethod()) {
+                            opDesc = operation;
+                            break;
+                        }
+                    }
+                }
+            }
+            // Note that opDesc might still be null
+            syncOperationDescription = opDesc;
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Synchronous operationDescription: " + syncOperationDescription);
+        }
+        return syncOperationDescription;
+    }
+
+
+    public String getAction() {
+        return getAnnoWebMethodAction();
+    }
+
+    public String getAnnoWebMethodAction() {
+        if (webMethodAction == null) {
+            if (getAnnoWebMethod() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoWebMethod().action())) {
+                webMethodAction = getAnnoWebMethod().action();
+            } else {
+                webMethodAction = WebMethod_Action_DEFAULT;
+            }
+        }
+        return webMethodAction;
+    }
+
+    public boolean isExcluded() {
+        return getAnnoWebMethodExclude();
+    }
+
+    public boolean getAnnoWebMethodExclude() {
+        if (webMethodExclude == null) {
+            // TODO: Validation: if this attribute specified, no other elements allowed per JSR-181 MR Sec 4.2, pg 17
+            // TODO: Validation: This element is not allowed on endpoint interfaces
+            // Unlike the elements with a String value, if the annotation is present, exclude will always 
+            // return a usable value since it will default to FALSE if the element is not present.
+            if (getAnnoWebMethod() != null) {
+                webMethodExclude = Boolean.valueOf(getAnnoWebMethod().exclude());
+            } else {
+                webMethodExclude = WebMethod_Exclude_DEFAULT;
+            }
+        }
+
+        return webMethodExclude.booleanValue();
+    }
+
+    // ==========================================
+    // ANNOTATION: RequestWrapper
+    // ==========================================
+    public RequestWrapper getAnnoRequestWrapper() {
+        if (requestWrapperAnnotation == null) {
+            if (!isDBC() && seiMethod != null) {
+                requestWrapperAnnotation = (RequestWrapper) 
+                    getAnnotation(seiMethod,RequestWrapper.class);
+            } else if (isDBC() && methodComposite != null) {
+                requestWrapperAnnotation = methodComposite.getRequestWrapperAnnot();
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get RequestWrapper annotation");
+                }
+            }
+        }
+        return requestWrapperAnnotation;
+    }
+
+    public String getRequestWrapperLocalName() {
+        return getAnnoRequestWrapperLocalName();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoRequestWrapperLocalName() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (requestWrapperLocalName == null) {
+            if (getAnnoRequestWrapper() != null
+                    && !DescriptionUtils.isEmpty(getAnnoRequestWrapper().localName())) {
+                requestWrapperLocalName = getAnnoRequestWrapper().localName();
+            } else {
+                // The default value of localName is the value of operationQName as
+                // defined in the WebMethod annotation. [JAX-WS Sec. 7.3, p. 80]
+                requestWrapperLocalName = getAnnoWebMethodOperationName();
+            }
+        }
+        return requestWrapperLocalName;
+    }
+
+    public String getRequestWrapperTargetNamespace() {
+        return getAnnoRequestWrapperTargetNamespace();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoRequestWrapperTargetNamespace() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (requestWrapperTargetNamespace == null) {
+            if (getAnnoRequestWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoRequestWrapper().targetNamespace())) {
+                requestWrapperTargetNamespace = getAnnoRequestWrapper().targetNamespace();
+            } else {
+                // The default value for targetNamespace is the target namespace of the SEI. [JAX-WS Sec 7.3, p. 80]
+                requestWrapperTargetNamespace =
+                        getEndpointInterfaceDescription().getTargetNamespace();
+            }
+        }
+        return requestWrapperTargetNamespace;
+    }
+
+    public String getRequestWrapperClassName() {
+        return getAnnoRequestWrapperClassName();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoRequestWrapperClassName() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (requestWrapperClassName == null) {
+            if (getAnnoRequestWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoRequestWrapper().className())) {
+                requestWrapperClassName = getAnnoRequestWrapper().className();
+            } else {
+                // There is no default for the RequestWrapper class name.  
+                // In such cases the programming layer (JAXWS) may use a programming spec specific
+                // mechanism to find the class, build the class, or operate without the class.
+                requestWrapperClassName = null;
+            }
+        }
+        return requestWrapperClassName;
+    }
+    
+    public String getRequestWrapperPartName(){
+    	return getAnnoRequestWrapperPartName();
+    }
+    
+    /**
+     * Return PartName for RequestWrapper annotation if one present.
+     * @return
+     */
+    public String getAnnoRequestWrapperPartName(){
+    	if(!isWrappedParameters()){
+    		return null;
+    	}
+        if (requestWrapperPartName == null) {
+            if (getAnnoRequestWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoRequestWrapper().partName())) {
+                requestWrapperPartName = getAnnoRequestWrapper().partName();
+            } else {
+                // There is no default for the RequestWrapper part name.  
+            	requestWrapperPartName = null;
+            }
+        }
+        if(log.isDebugEnabled()){
+            if(requestWrapperPartName!=null){
+                log.debug("RequestWrapperPartName ="+requestWrapperPartName);
+            }else{
+                log.debug("RequestWrapperPartName = NULL");
+            }
+        }
+        return requestWrapperPartName;
+    }
+    // ===========================================
+    // ANNOTATION: ResponseWrapper
+    // ===========================================
+    public ResponseWrapper getAnnoResponseWrapper() {
+        if (responseWrapperAnnotation == null) {
+            if (!isDBC() && seiMethod != null) {
+                responseWrapperAnnotation = (ResponseWrapper)
+                    getAnnotation(seiMethod,ResponseWrapper.class);
+            } else if (isDBC() && methodComposite != null) {
+                responseWrapperAnnotation = methodComposite.getResponseWrapperAnnot();
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get ResponseWrapper annotation");
+                }
+            }
+        }
+        return responseWrapperAnnotation;
+    }
+
+    public String getResponseWrapperLocalName() {
+        return getAnnoResponseWrapperLocalName();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoResponseWrapperLocalName() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (responseWrapperLocalName == null) {
+            if (getAnnoResponseWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoResponseWrapper().localName())) {
+                responseWrapperLocalName = getAnnoResponseWrapper().localName();
+            } else {
+                // The default value of localName is the value of operationQName as 
+                // defined in the WebMethod annotation appended with "Response". [JAX-WS Sec. 7.4, p. 81]
+                responseWrapperLocalName = getAnnoWebMethodOperationName() + "Response";
+            }
+        }
+        return responseWrapperLocalName;
+    }
+
+    public String getResponseWrapperTargetNamespace() {
+        return getAnnoResponseWrapperTargetNamespace();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoResponseWrapperTargetNamespace() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (responseWrapperTargetNamespace == null) {
+            if (getAnnoResponseWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoResponseWrapper().targetNamespace())) {
+                responseWrapperTargetNamespace = getAnnoResponseWrapper().targetNamespace();
+            } else {
+                // The default value for targetNamespace is the target namespace of the SEI. [JAX-WS Sec 7.3, p. 80]
+                responseWrapperTargetNamespace =
+                        getEndpointInterfaceDescription().getTargetNamespace();
+            }
+        }
+        return responseWrapperTargetNamespace;
+    }
+
+    public String getResponseWrapperClassName() {
+        return getAnnoResponseWrapperClassName();
+    }
+
+    /**
+     * For wrapped parameter style (based on the annotation and the WSDL), returns the wrapper
+     * value.  For non-wrapped (i.e. bare) parameter style, returns null.
+     *
+     * @return
+     */
+    public String getAnnoResponseWrapperClassName() {
+        if (!isWrappedParameters()) {
+            // A wrapper is only meaningful for wrapped parameters
+            return null;
+        }
+        if (responseWrapperClassName == null) {
+            if (getAnnoResponseWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoResponseWrapper().className())) {
+                responseWrapperClassName = getAnnoResponseWrapper().className();
+            } else {
+                // There is no default for the ResponseWrapper class name.  
+                // In such cases the programming layer (JAXWS) may use a programming spec specific
+                // mechanism to find the class, build the class, or operate without the class.
+                responseWrapperClassName = null;
+            }
+        }
+        return responseWrapperClassName;
+    }
+
+    public String getResponseWrapperPartName(){
+    	return getAnnoResponseWrapperPartName();
+    }
+    
+    /**
+     * return ResponseWrapper PartName if one present.
+     * @return
+     */
+    public String getAnnoResponseWrapperPartName(){
+    	if(!isWrappedParameters()){
+    		return null;
+    	}
+        if (responseWrapperPartName == null) {
+            if (getAnnoResponseWrapper() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoResponseWrapper().partName())) {
+                responseWrapperPartName = getAnnoResponseWrapper().partName();
+            } else {
+                // There is no default for the ResponseWrapper part name.  
+                responseWrapperPartName = null;
+            }
+        }
+        if(log.isDebugEnabled()){
+            if(responseWrapperPartName!=null){
+                log.debug("ResponseWrapperPartName ="+responseWrapperPartName);
+            }else{
+                log.debug("ResponseWrapperPartName = NULL");
+            }
+        }
+        return responseWrapperPartName;
+    }
+    // ===========================================
+    // ANNOTATION: WebFault
+    // ===========================================
+
+    /*
+     * TODO some of the WebFault stuff should be moved to FaultDescription
+     */
+
+    /*
+    *  TODO:  this will need revisited.  The problem is that a WebFault is not mapped 1:1 to an
+    *  OperationDescription.  We should do a better job caching the information.  For now, I'm
+    *  following the getWebParam() pattern.
+    *
+    *  This is gonna get complicated.  One other thing to consider is that a method (opdesc) may declare
+    *  several types of exceptions it throws
+    *
+    */
+
+    public FaultDescription[] getFaultDescriptions() {
+        return faultDescriptions;
+    }
+
+    public FaultDescription resolveFaultByExceptionName(String exceptionClassName) {
+        if (faultDescriptions != null) {
+            for (FaultDescription fd : faultDescriptions) {
+                if (exceptionClassName.equals(fd.getExceptionClassName()))
+                    return fd;
+            }
+        }
+        return null;
+    }
+
+    // ===========================================
+    // ANNOTATION: WebParam
+    // ===========================================
+    // Note that this annotation is handled by the ParameterDescripton.
+    // Methods are provided on OperationDescription as convenience methods.
+    public ParameterDescription[] getParameterDescriptions() {
+        return parameterDescriptions;
+    }
+
+    public ParameterDescription getParameterDescription(String parameterName) {
+        // TODO: Validation: For BARE paramaterUse, only a single IN our INOUT paramater and a single output (either return or OUT or INOUT) is allowed 
+        //       Per JSR-224, Sec 3.6.2.2, pg 37
+        ParameterDescription matchingParamDesc = null;
+        if (parameterName != null && !parameterName.equals("")) {
+            for (ParameterDescription paramDesc : parameterDescriptions) {
+                if (parameterName.equals(paramDesc.getParameterName())) {
+                    matchingParamDesc = paramDesc;
+                    break;
+                }
+            }
+        }
+        return matchingParamDesc;
+    }
+
+    public ParameterDescription getParameterDescription(int parameterNumber) {
+        return parameterDescriptions[parameterNumber];
+    }
+
+    public String[] getParamNames() {
+        return getAnnoWebParamNames();
+    }
+
+    public String[] getAnnoWebParamNames() {
+        if (webParamNames == null) {
+            ArrayList<String> buildNames = new ArrayList<String>();
+            ParameterDescription[] paramDescs = getParameterDescriptions();
+            for (ParameterDescription currentParamDesc : paramDescs) {
+                buildNames.add(currentParamDesc.getParameterName());
+            }
+            webParamNames = buildNames.toArray(new String[0]);
+        }
+        return webParamNames;
+    }
+
+    public String[] getAnnoWebParamTargetNamespaces() {
+        if (webParamTargetNamespace == null) {
+            ArrayList<String> buildTargetNS = new ArrayList<String>();
+            ParameterDescription[] paramDescs = getParameterDescriptions();
+            for (ParameterDescription currentParamDesc : paramDescs) {
+                buildTargetNS.add(currentParamDesc.getTargetNamespace());
+            }
+            webParamTargetNamespace = buildTargetNS.toArray(new String[0]);
+        }
+        return webParamTargetNamespace;
+    }
+
+    public String getAnnoWebParamTargetNamespace(String name) {
+        String returnTargetNS = null;
+        ParameterDescription paramDesc = getParameterDescription(name);
+        if (paramDesc != null) {
+            returnTargetNS = paramDesc.getTargetNamespace();
+        }
+        return returnTargetNS;
+    }
+
+
+    public Mode[] getAnnoWebParamModes() {
+        if (webParamMode == null) {
+            ArrayList<Mode> buildModes = new ArrayList<Mode>();
+            ParameterDescription[] paramDescs = getParameterDescriptions();
+            for (ParameterDescription currentParamDesc : paramDescs) {
+                buildModes.add(((ParameterDescriptionJava)currentParamDesc).getAnnoWebParamMode());
+            }
+            webParamMode = buildModes.toArray(new Mode[0]);
+        }
+        return webParamMode;
+    }
+
+    public boolean isAnnoWebParamHeader(String name) {
+        ParameterDescription paramDesc = getParameterDescription(name);
+        if (paramDesc != null) {
+            return paramDesc.isHeader();
+        }
+        return false;
+    }
+
+    // ===========================================
+    // ANNOTATION: WebResult
+    // ===========================================
+    public WebResult getAnnoWebResult() {
+        if (webResultAnnotation == null) {
+            if (!isDBC() && seiMethod != null) {
+                webResultAnnotation = (WebResult)
+                    getAnnotation(seiMethod,WebResult.class);
+            } else if (methodComposite != null) {
+                webResultAnnotation = methodComposite.getWebResultAnnot();
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get WebResult annotation");
+                }
+            }
+        }
+        return webResultAnnotation;
+    }
+
+    public boolean isWebResultAnnotationSpecified() {
+        return getAnnoWebResult() != null;
+    }
+
+    public boolean isOperationReturningResult() {
+        boolean isResult = false;
+        if (!isAnnoOneWay()) {
+            if (!isDBC() && seiMethod != null) {
+                if (seiMethod.getReturnType() != Void.TYPE) {
+                    isResult = true;
+                }
+            } else if (methodComposite != null) {
+                if (!DescriptionUtils.isEmpty(methodComposite.getReturnType()) &&
+                        !methodComposite.getReturnType().equals("void"))
+                    isResult = true;
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("No class to determine if result is returned");
+                }
+            }
+        }
+        return isResult;
+    }
+
+    public String getResultName() {
+        return getAnnoWebResultName();
+    }
+
+    public String getAnnoWebResultName() {
+        if (!isOperationReturningResult()) {
+            return null;
+        }
+        if (webResultName == null) {
+            if (getAnnoWebResult() != null && !DescriptionUtils.isEmpty(getAnnoWebResult().name()))
+            {
+                webResultName = getAnnoWebResult().name();
+            } else if (getAnnoSoapBindingStyle() == SOAPBinding.Style.DOCUMENT
+                    && getAnnoSoapBindingParameterStyle() == SOAPBinding.ParameterStyle.BARE) {
+                // Default for operation style DOCUMENT and paramater style BARE per JSR 181 MR Sec 4.5.1, pg 23
+                webResultName = getAnnoWebMethodOperationName() + "Response";
+
+            } else {
+                // Defeault value is "return" per JSR-181 MR Sec. 4.5.1, p. 22
+                webResultName = "return";
+            }
+        }
+        return webResultName;
+    }
+
+    public String getResultPartName() {
+        return getAnnoWebResultPartName();
+    }
+
+    public String getAnnoWebResultPartName() {
+        if (!isOperationReturningResult()) {
+            return null;
+        }
+        if (webResultPartName == null) {
+            if (getAnnoWebResult() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoWebResult().partName())) {
+                webResultPartName = getAnnoWebResult().partName();
+            } else {
+                // Default is the WebResult.name per JSR-181 MR Sec 4.5.1, pg 23
+                webResultPartName = getAnnoWebResultName();
+            }
+        }
+        return webResultPartName;
+    }
+
+    public String getResultTargetNamespace() {
+        return getAnnoWebResultTargetNamespace();
+    }
+
+    public String getAnnoWebResultTargetNamespace() {
+        if (!isOperationReturningResult()) {
+            return null;
+        }
+        if (webResultTargetNamespace == null) {
+            if (getAnnoWebResult() != null &&
+                    !DescriptionUtils.isEmpty(getAnnoWebResult().targetNamespace())) {
+                webResultTargetNamespace = getAnnoWebResult().targetNamespace();
+            } else if (getAnnoSoapBindingStyle() == SOAPBinding.Style.DOCUMENT
+                    && getAnnoSoapBindingParameterStyle() == SOAPBinding.ParameterStyle.WRAPPED
+                    && !getAnnoWebResultHeader()) {
+                // Default for operation style DOCUMENT and paramater style WRAPPED and the return value
+                // does not map to a header per JSR-181 MR Sec 4.5.1, pg 23-24
+                webResultTargetNamespace = WebResult_TargetNamespace_DEFAULT;
+            } else {
+                // Default is the namespace from the WebService per JSR-181 MR Sec 4.5.1, pg 23-24
+                webResultTargetNamespace =
+                        ((EndpointDescriptionJava)getEndpointInterfaceDescription()
+                                .getEndpointDescription()).getAnnoWebServiceTargetNamespace();
+            }
+
+        }
+        return webResultTargetNamespace;
+    }
+
+    public boolean isResultHeader() {
+        return getAnnoWebResultHeader();
+    }
+
+    public boolean getAnnoWebResultHeader() {
+        if (!isOperationReturningResult()) {
+            return false;
+        }
+        if (webResultHeader == null) {
+            if (getAnnoWebResult() != null) {
+                // Unlike the elements with a String value, if the annotation is present, exclude will always 
+                // return a usable value since it will default to FALSE if the element is not present.
+                webResultHeader = Boolean.valueOf(getAnnoWebResult().header());
+            } else {
+                webResultHeader = WebResult_Header_DEFAULT;
+            }
+        }
+        return webResultHeader.booleanValue();
+    }
+
+    // ===========================================
+    // ANNOTATION: SOAPBinding
+    // ===========================================
+    public SOAPBinding getAnnoSoapBinding() {
+        // TODO: VALIDATION: Only style of DOCUMENT allowed on Method annotation; remember to check the Type's style setting also
+        //       JSR-181 Sec 4.7 p. 28
+        if (soapBindingAnnotation == null) {
+            if (!isDBC() && seiMethod != null) {
+                soapBindingAnnotation = (SOAPBinding)
+                    getAnnotation(seiMethod,SOAPBinding.class);
+            } else if (isDBC() && methodComposite != null) {
+                soapBindingAnnotation = methodComposite.getSoapBindingAnnot();
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get SOAP Binding annotation");
+                }
+            }
+        }
+        return soapBindingAnnotation;
+    }
+
+    public javax.jws.soap.SOAPBinding.Style getSoapBindingStyle() {
+        return getAnnoSoapBindingStyle();
+    }
+
+    public javax.jws.soap.SOAPBinding.Style getAnnoSoapBindingStyle() {
+        if (soapBindingStyle == null) {
+            if (getAnnoSoapBinding() != null && getAnnoSoapBinding().style() != null) {
+                soapBindingStyle = getAnnoSoapBinding().style();
+            } else {
+                // Per JSR-181 MR Sec 4.7, pg 28: if not specified, use the Type value.
+                soapBindingStyle = getEndpointInterfaceDescription().getSoapBindingStyle();
+            }
+        }
+        return soapBindingStyle;
+    }
+
+    public javax.jws.soap.SOAPBinding.Use getSoapBindingUse() {
+        return getAnnoSoapBindingUse();
+    }
+
+    public javax.jws.soap.SOAPBinding.Use getAnnoSoapBindingUse() {
+        if (soapBindingUse == null) {
+            if (getAnnoSoapBinding() != null && getAnnoSoapBinding().use() != null) {
+                soapBindingUse = getAnnoSoapBinding().use();
+            } else {
+                // Per JSR-181 MR Sec 4.7, pg 28: if not specified, use the Type value.
+                soapBindingUse = getEndpointInterfaceDescription().getSoapBindingUse();
+            }
+        }
+        return soapBindingUse;
+    }
+
+    public javax.jws.soap.SOAPBinding.ParameterStyle getSoapBindingParameterStyle() {
+        return getAnnoSoapBindingParameterStyle();
+    }
+
+    public javax.jws.soap.SOAPBinding.ParameterStyle getAnnoSoapBindingParameterStyle() {
+        if (soapBindingParameterStyle == null) {
+            if (getAnnoSoapBinding() != null && getAnnoSoapBinding().parameterStyle() != null) {
+                soapBindingParameterStyle = getAnnoSoapBinding().parameterStyle();
+            } else {
+                // Per JSR-181 MR Sec 4.7, pg 28: if not specified, use the Type value.
+                soapBindingParameterStyle =
+                        getEndpointInterfaceDescription().getSoapBindingParameterStyle();
+            }
+        }
+        return soapBindingParameterStyle;
+    }
+    
+    // ===========================================
+    // ANNOTATION: Action
+    // ===========================================
+    public Action getAnnoAction() {
+        if (actionAnnotation == null) {
+            if (!isDBC() && seiMethod != null) {
+                actionAnnotation = (Action) getAnnotation(seiMethod, Action.class);
+            }
+            else if (methodComposite != null) {
+                actionAnnotation = methodComposite.getActionAnnot();
+            }
+            else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get Action annotation.");
+                }
+            }
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("getAnnoAction: " + actionAnnotation);
+        }
+        
+        return actionAnnotation;
+    }
+    
+    private String getInputAction() {
+        String inputAction = null;
+        Action action = getAnnoAction();
+        
+        if (action != null) {
+            inputAction = action.input();
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("getInputAction: " + inputAction);
+        }
+        
+        return inputAction;
+    }
+    
+    private String getOutputAction() {
+        String outputAction = null;
+        Action action = getAnnoAction();
+        
+        if (action != null) {
+            outputAction = action.output();
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("getOutputAction: " + outputAction);
+        }
+        
+        return outputAction;
+    }
+    
+    private FaultAction[] getFaultActions() {
+        FaultAction[] faultActions = null;
+        Action action = getAnnoAction();
+        
+        if (action !=  null) {
+            faultActions = action.fault();
+        }
+        
+        if (log.isDebugEnabled()) {
+            log.debug("getFaultActions: " + Arrays.toString(faultActions));
+        }
+        
+        return faultActions;
+    }
+
+    // ===========================================
+    // ANNOTATION: OneWay
+    // ===========================================
+    public Oneway getAnnoOneway() {
+        if (onewayAnnotation == null) {
+            // Get the onew-way annotation from either the method composite (server-side)
+            // or from the SEI method (client-side).  
+            if (isDBC() && methodComposite != null) {
+                if (methodComposite.isOneWay()) {
+                    onewayAnnotation = OneWayAnnot.createOneWayAnnotImpl();
+                }
+            } else if (!isDBC() && seiMethod != null) {
+                onewayAnnotation = (Oneway) getAnnotation(seiMethod,Oneway.class);
+            } else {
+                if (log.isDebugEnabled()) {
+                    log.debug("Unable to get OneWay annotation");
+                }
+            }
+        }
+        return onewayAnnotation;
+    }
+
+    public boolean isOneWay() {
+        return isAnnoOneWay();
+    }
+
+    public boolean isAnnoOneWay() {
+        if (onewayIsOneway == null) {
+            if (getAnnoOneway() != null) {
+                // The presence of the annotation indicates the method is oneway
+                onewayIsOneway = Boolean.TRUE;
+            } else {
+                // If the annotation is not present, the default is this is NOT a One Way method
+                onewayIsOneway = Boolean.FALSE;
+            }
+        }
+        return onewayIsOneway.booleanValue();
+    }
+
+    private boolean isDBC() {
+        if (methodComposite != null)
+            return true;
+        else
+            return false;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.OperationDescription#getResultType()
+     */
+    public Class getResultType() {
+        Class returnClass = null;
+        if (!isDBC() && getSEIMethod() != null) {
+            Method seiMethod = this.getSEIMethod();
+            returnClass = seiMethod.getReturnType();
+        } else if (methodComposite != null) {
+            returnClass = methodComposite.getReturnTypeClass();
+        } else {
+            if (log.isDebugEnabled()) {
+                log.debug("Unable to get result type from null class");
+            }
+        }
+        return returnClass;
+    }
+
+    /* (non-Javadoc)
+     * @see org.apache.axis2.jaxws.description.OperationDescription#getResultActualType()
+     */
+    public Class getResultActualType() {
+        if(resultActualTypeClazz == null) {
+            resultActualTypeClazz = findResultActualType();    
+        }
+        return resultActualTypeClazz;
+    }
+    
+    public Class findResultActualType() {
+        // TODO: Fix this!  it isn't doing the right thing for DBC as noted below with FIXME comments
+        //       This is used to marshall the rsp on the service (dbc) and demarshall on the client (reflection)
+        //       But we shouldn't get an async OpDesc on the service since getDispatchableOperation(QN) removes them.
+
+        Class returnType = getResultType();
+        if (returnType == null) {
+            return null;
+        }
+        if (isJAXWSAsyncClientMethod()) {
+            //pooling implementation
+            if (Response.class == returnType) {
+                if (!isDBC()) {
+                    Type type = seiMethod.getGenericReturnType();
+                    ParameterizedType pType = (ParameterizedType)type;
+                    Type aType = pType.getActualTypeArguments()[0];
+                    if (aType != null && ParameterizedType.class.isInstance(aType)) {
+                        return (Class)((ParameterizedType)aType).getRawType();
+                    }
+                    return (Class)aType;
+                } else {
+                    // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+                    //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+                    //        This needs to return T for Response<T>, or List for Response<List<T>>>
+                    return returnType;
+                }
+            }
+            //Callback Implementation
+            else {
+                // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+                //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+                //        This needs to find and return T for AsyncHandler<T>, or List for AsyncHandler<List<T>>>
+                Type[] type = getGenericParameterTypes();
+                Class parameters[] = getParameterTypes();
+                int i = 0;
+                for (Class param : parameters) {
+                    if (AsyncHandler.class.isAssignableFrom(param)) {
+                        ParameterizedType pType = (ParameterizedType)type[i];
+                        Type aType = pType.getActualTypeArguments()[0];
+                        if (aType != null && ParameterizedType.class.isInstance(aType)) {
+                            return (Class)((ParameterizedType)aType).getRawType();
+                        }
+                        return (Class)aType;
+                    }
+                    i++;
+                }
+            }
+        }
+
+        return returnType;
+    }
+
+
+    private Type[] getGenericParameterTypes() {
+        if (isDBC()) {
+            // FIXME: This doesn't work for DBC.  That's OK for now because DBC isn't used on the client side
+            //        yet; the client is all Java Reflection.  On the Service side, the Async methods are not used.
+            //        And this method is only used to parse out the JAX-WS Async parameter types to find
+            //        AsyncHandler<T>.  The problem with the code that was removed is that a Type can not be
+            //        instantiated, so we can't new up a Type inside the PDC.
+        	throw ExceptionFactory.makeWebServiceException(new UnsupportedOperationException(Messages.getMessage("genParamTypesErr")));
+//           Type [] type = new Type[parameterDescriptions.length];
+//           for (int i=0; i < parameterDescriptions.length; i++){
+//               type[i] = ((ParameterDescriptionImpl) parameterDescriptions[i]).getParameterActualGenericType();
+//           }
+//           return type;
+        } else {
+            Type [] type = seiMethod.getGenericParameterTypes();
+            return type;
+        }
+    }
+
+    private Class[] getParameterTypes() {
+        if (isDBC()) {
+            Class [] parameters = new Class[parameterDescriptions.length];
+            for (int i = 0; i < parameterDescriptions.length; i++) {
+                parameters[i] = parameterDescriptions[i].getParameterType();
+            }
+            return parameters;
+        } else {
+            Class [] parameters = seiMethod.getParameterTypes();
+            return parameters;
+        }
+    }
+
+    /*
+    * (non-Javadoc)
+    * @see org.apache.axis2.jaxws.description.OperationDescription#isJAXWSAsyncClientMethod()
+    */
+    public boolean isJAXWSAsyncClientMethod() {
+        boolean answer = false;
+        String methodName = null;
+        String returnTypeName = null;
+        if (isDBC()) {
+            methodName = getMethodDescriptionComposite().getMethodName();
+            returnTypeName = getMethodDescriptionComposite().getReturnType();
+        } else {
+            Method method = this.getSEIMethod();
+            if (method != null) {
+                methodName = method.getName();
+                returnTypeName = method.getReturnType().getName();
+            }
+        }
+        if (methodName != null && returnTypeName != null) {
+            answer = (returnTypeName.contains(Response.class.getName()) ||
+                    returnTypeName.contains(Future.class.getName()));
+        }
+        if (log.isDebugEnabled()) {
+            log.debug("Method = " + methodName);
+            log.debug("Return Type = " + returnTypeName);
+            log.debug("Is client async = " + answer);
+        }
+        return answer;
+    }
+
+    /**
+     * Return the Service Implementation method for this operation IFF it has been set by a previous
+     * call to getMethodFromServiceImpl(Class serviceImplClass).  Otherwise a null is returned.
+     *
+     * @return
+     */
+    private Method getMethodFromServiceImpl() {
+        return serviceImplMethod;
+
+    }
+
+    public Method getMethodFromServiceImpl(Class serviceImpl) {
+
+        // TODO: This doesn't support overloaded methods in the service impl  This is
+        //       DIFFERENT than overloaded WSDL operations (which aren't supported).  We
+        //       MUST support overloaded service impl methods as long as they have different
+        //       wsdl operation names.  For example:
+        //  ServiceImple Class          SEI Class
+        //                              @WebMethod.name = Foo1
+        //  void foo()                  void foo()
+        //                              @WebMethod.name = Foo2
+        //  void foo(int)               void foo(int)
+        //                              @WebMethod.name = Foo3
+        //  void foo(String)            void foo(String)
+        //
+        //  There will be two OpDescs, Foo1 and Foo2; the incoming wsdl operation will correctly identify
+        //  which OpDesc.  However, to return the correct service impl method, we need to compare the
+        //  signatures, not just the method names.
+        if (!serviceImplMethodFound) {
+            Method[] methods = serviceImpl.getMethods();
+            String opDescMethodName = getJavaMethodName();
+            ParameterDescription[] paramDesc = getParameterDescriptions();
+            // TODO: As noted above, a full signature is necessary, not just number of params
+            int numberOfParams = 0;
+            if (paramDesc != null) {
+                numberOfParams = paramDesc.length;
+            }
+
+            // Loop through all the methods on the service impl and find the method that maps
+            // to this OperationDescripton
+            for (Method checkMethod : methods) {
+                if (checkMethod.getName().equals(opDescMethodName)) {
+                    Class[] methodParams = checkMethod.getParameterTypes();
+                    // TODO: As noted above, a full signature is necessary, not just number of params
+                    if (methodParams.length == numberOfParams) {
+                        if (paramTypesMatch(paramDesc, methodParams)) {
+                            serviceImplMethod = checkMethod;
+                            break;
+                        }
+                    }
+                }
+            }
+            serviceImplMethodFound = true;
+        }
+        return serviceImplMethod;
+    }
+
+    /**
+     * This method will compare the types of the parameters in a <code>ParameterDescription</code>
+     * vs. the type of the arguments in the parameters of a <code>Method</code>.
+     *
+     * @param paramDescs   - <code>ParameterDescription</code>[]
+     * @param methodParams - <code>Class</code>[]
+     * @return - <code>boolean</code>
+     */
+    private boolean paramTypesMatch(ParameterDescription[] paramDescs, Class[]
+            methodParams) {
+        for (int i = 0; i < paramDescs.length; i++) {
+            String mParamType = methodParams[i].getName();
+            String pdType = getPDType(paramDescs[i]);
+            if (mParamType == null || !mParamType.equals(pdType)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This will get a <code>String</code> representing the parameter class of a
+     * <code>ParameterDescription</code>.
+     *
+     * @param pd - <code>ParameterDescrition</code>
+     * @return - <code>String</code>
+     */
+    private String getPDType(ParameterDescription pd) {
+        String type = null;
+        if (pd.getParameterType() != null) {
+            type = pd.getParameterType().getName();
+        } else if (pd.getParameterActualType() != null) {
+            type = pd.getParameterActualType().getName();
+        }
+        return type;
+    }
+
+    public OperationRuntimeDescription getOperationRuntimeDesc(String name) {
+        // TODO Add toString support
+        return runtimeDescMap.get(name);
+    }
+
+    public void setOperationRuntimeDesc(OperationRuntimeDescription ord) {
+        // TODO Add toString support
+        runtimeDescMap.put(ord.getKey(), ord);
+    }
+    
+    public boolean isListType() {
+    	return isListType;
+    }
+    
+    /**
+     * This method will return the namespace for the BindingInput that this operation
+     * specifies. It will first look for a namespace on the WSDL Binding object and then 
+     * default to the web service's target namespace.
+     */
+    public String getBindingInputNamespace() {

[... 423 lines stripped ...]