private void WriteReturnMappings(CodeMemberMethod codeMethod, CodeExpression invoke, SoapParameters parameters, string resultsName)
 {
     if ((parameters.Return == null) && (parameters.OutParameters.Count == 0))
     {
         codeMethod.Statements.Add(new CodeExpressionStatement(invoke));
     }
     else
     {
         codeMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(object[]), resultsName, invoke));
         int num = (parameters.Return == null) ? 0 : 1;
         for (int i = 0; i < parameters.OutParameters.Count; i++)
         {
             SoapParameter parameter = (SoapParameter) parameters.OutParameters[i];
             CodeExpression left = new CodeArgumentReferenceExpression(parameter.name);
             CodeExpression expression = new CodeArrayIndexerExpression();
             ((CodeArrayIndexerExpression) expression).TargetObject = new CodeVariableReferenceExpression(resultsName);
             ((CodeArrayIndexerExpression) expression).Indices.Add(new CodePrimitiveExpression(num++));
             expression = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameter.mapping, base.ServiceImporter.CodeGenerator), expression);
             codeMethod.Statements.Add(new CodeAssignStatement(left, expression));
             if (parameter.mapping.CheckSpecified)
             {
                 left = new CodeArgumentReferenceExpression(parameter.name + "Specified");
                 expression = new CodeArrayIndexerExpression();
                 ((CodeArrayIndexerExpression) expression).TargetObject = new CodeVariableReferenceExpression(resultsName);
                 ((CodeArrayIndexerExpression) expression).Indices.Add(new CodePrimitiveExpression(num++));
                 expression = new CodeCastExpression(typeof(bool).FullName, expression);
                 codeMethod.Statements.Add(new CodeAssignStatement(left, expression));
             }
         }
         if (parameters.Return != null)
         {
             CodeExpression expression3 = new CodeArrayIndexerExpression();
             ((CodeArrayIndexerExpression) expression3).TargetObject = new CodeVariableReferenceExpression(resultsName);
             ((CodeArrayIndexerExpression) expression3).Indices.Add(new CodePrimitiveExpression(0));
             expression3 = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator), expression3);
             codeMethod.Statements.Add(new CodeMethodReturnStatement(expression3));
         }
     }
 }
        void WriteReturnMappings(CodeMemberMethod codeMethod, CodeExpression invoke, SoapParameters parameters, string resultsName) {
            if (parameters.Return == null && parameters.OutParameters.Count == 0) {
                codeMethod.Statements.Add(new CodeExpressionStatement(invoke));
            }
            else {
                codeMethod.Statements.Add(new CodeVariableDeclarationStatement(typeof(object[]), resultsName, invoke));

                int count = parameters.Return == null ? 0 : 1;
                for (int i = 0; i < parameters.OutParameters.Count; i++) {
                    SoapParameter parameter = (SoapParameter)parameters.OutParameters[i];
                    CodeExpression target = new CodeArgumentReferenceExpression(parameter.name);
                    CodeExpression value = new CodeArrayIndexerExpression();
                    ((CodeArrayIndexerExpression)value).TargetObject = new CodeVariableReferenceExpression(resultsName);
                    ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(count++));
                    value = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameter.mapping, ServiceImporter.CodeGenerator), value);
                    codeMethod.Statements.Add(new CodeAssignStatement(target, value));
                    if (parameter.mapping.CheckSpecified) {
                        target = new CodeArgumentReferenceExpression(parameter.name + "Specified");
                        value = new CodeArrayIndexerExpression();
                        ((CodeArrayIndexerExpression) value).TargetObject = new CodeVariableReferenceExpression(resultsName);
                        ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(count++));
                        value = new CodeCastExpression(typeof(bool).FullName, value);
                        codeMethod.Statements.Add(new CodeAssignStatement(target, value));
                    }
                }

                if (parameters.Return != null) {
                    CodeExpression value = new CodeArrayIndexerExpression();
                    ((CodeArrayIndexerExpression)value).TargetObject = new CodeVariableReferenceExpression(resultsName);
                    ((CodeArrayIndexerExpression)value).Indices.Add(new CodePrimitiveExpression(0));
                    value = new CodeCastExpression(WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator), value);
                    codeMethod.Statements.Add(new CodeMethodReturnStatement(value));
                }
            }
        }
 protected override CodeMemberMethod GenerateMethod()
 {
     Message outputMessage;
     SoapBodyBinding binding2;
     MessageBinding output;
     bool flag;
     SoapOperationBinding binding5 = (SoapOperationBinding) base.OperationBinding.Extensions.Find(typeof(SoapOperationBinding));
     if (binding5 == null)
     {
         throw base.OperationBindingSyntaxException(System.Web.Services.Res.GetString("MissingSoapOperationBinding0"));
     }
     SoapBindingStyle soapBindingStyle = binding5.Style;
     if (soapBindingStyle == SoapBindingStyle.Default)
     {
         soapBindingStyle = this.SoapBinding.Style;
     }
     if (soapBindingStyle == SoapBindingStyle.Default)
     {
         soapBindingStyle = SoapBindingStyle.Document;
     }
     string[] parameterOrder = base.Operation.ParameterOrder;
     Message inputMessage = base.InputMessage;
     MessageBinding input = base.OperationBinding.Input;
     SoapBodyBinding soapBodyBinding = (SoapBodyBinding) base.OperationBinding.Input.Extensions.Find(typeof(SoapBodyBinding));
     if (soapBodyBinding == null)
     {
         base.UnsupportedOperationBindingWarning(System.Web.Services.Res.GetString("MissingSoapBodyInputBinding0"));
         return null;
     }
     if (base.Operation.Messages.Output != null)
     {
         outputMessage = base.OutputMessage;
         output = base.OperationBinding.Output;
         binding2 = (SoapBodyBinding) base.OperationBinding.Output.Extensions.Find(typeof(SoapBodyBinding));
         if (binding2 == null)
         {
             base.UnsupportedOperationBindingWarning(System.Web.Services.Res.GetString("MissingSoapBodyOutputBinding0"));
             return null;
         }
     }
     else
     {
         outputMessage = null;
         output = null;
         binding2 = null;
     }
     CodeAttributeDeclarationCollection metadata = new CodeAttributeDeclarationCollection();
     this.PrepareHeaders(input);
     if (output != null)
     {
         this.PrepareHeaders(output);
     }
     string name = null;
     string str = (!string.IsNullOrEmpty(input.Name) && (soapBindingStyle != SoapBindingStyle.Rpc)) ? input.Name : base.Operation.Name;
     str = XmlConvert.DecodeName(str);
     if (output != null)
     {
         name = (!string.IsNullOrEmpty(output.Name) && (soapBindingStyle != SoapBindingStyle.Rpc)) ? output.Name : (base.Operation.Name + "Response");
         name = XmlConvert.DecodeName(name);
     }
     this.GenerateExtensionMetadata(metadata);
     this.GenerateHeaders(metadata, soapBodyBinding.Use, soapBindingStyle == SoapBindingStyle.Rpc, input, output);
     MessagePart[] messageParts = this.GetMessageParts(inputMessage, soapBodyBinding);
     if (!this.CheckMessageStyles(base.MethodName, messageParts, soapBodyBinding, soapBindingStyle, out flag))
     {
         return null;
     }
     MessagePart[] parts = null;
     if (outputMessage != null)
     {
         bool flag2;
         parts = this.GetMessageParts(outputMessage, binding2);
         if (!this.CheckMessageStyles(base.MethodName, parts, binding2, soapBindingStyle, out flag2))
         {
             return null;
         }
         if (flag != flag2)
         {
             flag = false;
         }
     }
     bool flag3 = ((soapBindingStyle != SoapBindingStyle.Rpc) && flag) || ((soapBodyBinding.Use == SoapBindingUse.Literal) && (soapBindingStyle == SoapBindingStyle.Rpc));
     XmlMembersMapping request = this.ImportMessage(str, messageParts, soapBodyBinding, soapBindingStyle, flag);
     if (request == null)
     {
         return null;
     }
     XmlMembersMapping response = null;
     if (outputMessage != null)
     {
         response = this.ImportMessage(name, parts, binding2, soapBindingStyle, flag);
         if (response == null)
         {
             return null;
         }
     }
     string str3 = CodeIdentifier.MakeValid(XmlConvert.DecodeName(base.Operation.Name));
     if (base.ClassName == str3)
     {
         str3 = "Call" + str3;
     }
     string identifier = base.MethodNames.AddUnique(CodeIdentifier.MakeValid(XmlConvert.DecodeName(str3)), base.Operation);
     bool flag4 = str3 != identifier;
     CodeIdentifiers identifiers = new CodeIdentifiers(false);
     identifiers.AddReserved(identifier);
     SoapParameters parameters = new SoapParameters(request, response, parameterOrder, base.MethodNames);
     foreach (SoapParameter parameter in parameters.Parameters)
     {
         if ((parameter.IsOut || parameter.IsByRef) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReferenceParameters))
         {
             base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportReferenceParameters", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name }));
             return null;
         }
         parameter.name = identifiers.AddUnique(parameter.name, null);
         if (parameter.mapping.CheckSpecified)
         {
             parameter.specifiedName = identifiers.AddUnique(parameter.name + "Specified", null);
         }
     }
     if ((base.Style != ServiceDescriptionImportStyle.Client) || flag4)
     {
         this.BeginMetadata();
         if (flag4)
         {
             this.AddMetadataProperty("MessageName", identifier);
         }
         this.EndMetadata(metadata, typeof(WebMethodAttribute), null);
     }
     this.BeginMetadata();
     if ((flag3 && (request.ElementName.Length > 0)) && (request.ElementName != identifier))
     {
         this.AddMetadataProperty("RequestElementName", request.ElementName);
     }
     if (request.Namespace != null)
     {
         this.AddMetadataProperty("RequestNamespace", request.Namespace);
     }
     if (response == null)
     {
         this.AddMetadataProperty("OneWay", true);
     }
     else
     {
         if ((flag3 && (response.ElementName.Length > 0)) && (response.ElementName != (identifier + "Response")))
         {
             this.AddMetadataProperty("ResponseElementName", response.ElementName);
         }
         if (response.Namespace != null)
         {
             this.AddMetadataProperty("ResponseNamespace", response.Namespace);
         }
     }
     if (soapBindingStyle == SoapBindingStyle.Rpc)
     {
         if (soapBodyBinding.Use != SoapBindingUse.Encoded)
         {
             this.AddMetadataProperty("Use", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapBodyBinding.Use, "G")));
         }
         this.EndMetadata(metadata, typeof(SoapRpcMethodAttribute), binding5.SoapAction);
     }
     else
     {
         this.AddMetadataProperty("Use", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapBodyBinding.Use, "G")));
         this.AddMetadataProperty("ParameterStyle", (CodeExpression) new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapParameterStyle).FullName), Enum.Format(typeof(SoapParameterStyle), flag ? SoapParameterStyle.Wrapped : SoapParameterStyle.Bare, "G")));
         this.EndMetadata(metadata, typeof(SoapDocumentMethodAttribute), binding5.SoapAction);
     }
     base.IsEncodedBinding = base.IsEncodedBinding || (soapBodyBinding.Use == SoapBindingUse.Encoded);
     CodeAttributeDeclarationCollection[] parameterAttributes = new CodeAttributeDeclarationCollection[parameters.Parameters.Count + parameters.CheckSpecifiedCount];
     int index = 0;
     CodeAttributeDeclaration declaration = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
     foreach (SoapParameter parameter2 in parameters.Parameters)
     {
         parameterAttributes[index] = new CodeAttributeDeclarationCollection();
         if (soapBodyBinding.Use == SoapBindingUse.Encoded)
         {
             this.soapExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, parameter2.name != parameter2.mapping.MemberName);
         }
         else
         {
             string ns = (soapBindingStyle == SoapBindingStyle.Rpc) ? parameter2.mapping.Namespace : (parameter2.IsOut ? response.Namespace : request.Namespace);
             bool forceUseMemberName = parameter2.name != parameter2.mapping.MemberName;
             this.xmlExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, ns, forceUseMemberName);
             if (parameter2.mapping.CheckSpecified)
             {
                 index++;
                 parameterAttributes[index] = new CodeAttributeDeclarationCollection();
                 this.xmlExporter.AddMappingMetadata(parameterAttributes[index], parameter2.mapping, ns, parameter2.specifiedName != (parameter2.mapping.MemberName + "Specified"));
                 parameterAttributes[index].Add(declaration);
             }
         }
         if ((parameterAttributes[index].Count > 0) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ParameterAttributes))
         {
             base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportParameterAttributes", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name }));
             return null;
         }
         index++;
     }
     CodeFlags[] codeFlags = SoapParameter.GetCodeFlags(parameters.Parameters, parameters.CheckSpecifiedCount);
     string[] parameterTypeNames = SoapParameter.GetTypeFullNames(parameters.Parameters, parameters.CheckSpecifiedCount, base.ServiceImporter.CodeGenerator);
     string returnTypeName = (parameters.Return == null) ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator);
     CodeMemberMethod codeMethod = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, str3, codeFlags, parameterTypeNames, SoapParameter.GetNames(parameters.Parameters, parameters.CheckSpecifiedCount), parameterAttributes, returnTypeName, metadata, CodeFlags.IsPublic | ((base.Style == ServiceDescriptionImportStyle.Client) ? ((CodeFlags) 0) : CodeFlags.IsAbstract));
     codeMethod.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true));
     if (parameters.Return != null)
     {
         if (soapBodyBinding.Use == SoapBindingUse.Encoded)
         {
             this.soapExporter.AddMappingMetadata(codeMethod.ReturnTypeCustomAttributes, parameters.Return, parameters.Return.ElementName != (identifier + "Result"));
         }
         else
         {
             this.xmlExporter.AddMappingMetadata(codeMethod.ReturnTypeCustomAttributes, parameters.Return, response.Namespace, parameters.Return.ElementName != (identifier + "Result"));
         }
         if ((codeMethod.ReturnTypeCustomAttributes.Count != 0) && !base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReturnTypeAttributes))
         {
             base.UnsupportedOperationWarning(System.Web.Services.Res.GetString("CodeGenSupportReturnTypeAttributes", new object[] { base.ServiceImporter.CodeGenerator.GetType().Name }));
             return null;
         }
     }
     string resultsName = identifiers.MakeUnique("results");
     if (base.Style == ServiceDescriptionImportStyle.Client)
     {
         bool flag6 = (base.ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateOldAsync) != CodeGenerationOptions.None;
         bool flag7 = (((base.ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateNewAsync) != CodeGenerationOptions.None) && base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareEvents)) && base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareDelegates);
         CodeExpression[] invokeParams = new CodeExpression[2];
         this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount);
         CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Invoke", invokeParams);
         this.WriteReturnMappings(codeMethod, invoke, parameters, resultsName);
         if (flag6)
         {
             int num2 = parameters.InParameters.Count + parameters.InCheckSpecifiedCount;
             string[] typeFullNames = new string[num2 + 2];
             SoapParameter.GetTypeFullNames(parameters.InParameters, typeFullNames, 0, parameters.InCheckSpecifiedCount, base.ServiceImporter.CodeGenerator);
             typeFullNames[num2] = typeof(AsyncCallback).FullName;
             typeFullNames[num2 + 1] = typeof(object).FullName;
             string[] strArray4 = new string[num2 + 2];
             SoapParameter.GetNames(parameters.InParameters, strArray4, 0, parameters.InCheckSpecifiedCount);
             strArray4[num2] = "callback";
             strArray4[num2 + 1] = "asyncState";
             CodeFlags[] parameterFlags = new CodeFlags[num2 + 2];
             CodeMemberMethod method2 = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, "Begin" + identifier, parameterFlags, typeFullNames, strArray4, typeof(IAsyncResult).FullName, null, CodeFlags.IsPublic);
             method2.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true));
             invokeParams = new CodeExpression[4];
             this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount);
             invokeParams[2] = new CodeArgumentReferenceExpression("callback");
             invokeParams[3] = new CodeArgumentReferenceExpression("asyncState");
             invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "BeginInvoke", invokeParams);
             method2.Statements.Add(new CodeMethodReturnStatement(invoke));
             int num3 = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount;
             string[] strArray5 = new string[num3 + 1];
             SoapParameter.GetTypeFullNames(parameters.OutParameters, strArray5, 1, parameters.OutCheckSpecifiedCount, base.ServiceImporter.CodeGenerator);
             strArray5[0] = typeof(IAsyncResult).FullName;
             string[] strArray6 = new string[num3 + 1];
             SoapParameter.GetNames(parameters.OutParameters, strArray6, 1, parameters.OutCheckSpecifiedCount);
             strArray6[0] = "asyncResult";
             CodeFlags[] flagsArray3 = new CodeFlags[num3 + 1];
             for (int i = 0; i < num3; i++)
             {
                 flagsArray3[i + 1] = CodeFlags.IsOut;
             }
             CodeMemberMethod method3 = WebCodeGenerator.AddMethod(base.CodeTypeDeclaration, "End" + identifier, flagsArray3, strArray5, strArray6, (parameters.Return == null) ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator), null, CodeFlags.IsPublic);
             method3.Comments.Add(new CodeCommentStatement(System.Web.Services.Res.GetString("CodeRemarks"), true));
             CodeExpression expression2 = new CodeArgumentReferenceExpression("asyncResult");
             invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "EndInvoke", new CodeExpression[] { expression2 });
             this.WriteReturnMappings(method3, invoke, parameters, resultsName);
         }
         if (!flag7)
         {
             return codeMethod;
         }
         string str8 = ProtocolImporter.MethodSignature(identifier, returnTypeName, codeFlags, parameterTypeNames);
         DelegateInfo info = (DelegateInfo) base.ExportContext[str8];
         if (info == null)
         {
             string handlerType = base.ClassNames.AddUnique(identifier + "CompletedEventHandler", identifier);
             string handlerArgs = base.ClassNames.AddUnique(identifier + "CompletedEventArgs", identifier);
             info = new DelegateInfo(handlerType, handlerArgs);
         }
         string handlerName = base.MethodNames.AddUnique(identifier + "Completed", identifier);
         string methodName = base.MethodNames.AddUnique(identifier + "Async", identifier);
         string callbackMember = base.MethodNames.AddUnique(identifier + "OperationCompleted", identifier);
         string callbackName = base.MethodNames.AddUnique("On" + identifier + "OperationCompleted", identifier);
         WebCodeGenerator.AddEvent(base.CodeTypeDeclaration.Members, info.handlerType, handlerName);
         WebCodeGenerator.AddCallbackDeclaration(base.CodeTypeDeclaration.Members, callbackMember);
         string[] names = SoapParameter.GetNames(parameters.InParameters, parameters.InCheckSpecifiedCount);
         string userState = ProtocolImporter.UniqueName("userState", names);
         CodeMemberMethod method4 = WebCodeGenerator.AddAsyncMethod(base.CodeTypeDeclaration, methodName, SoapParameter.GetTypeFullNames(parameters.InParameters, parameters.InCheckSpecifiedCount, base.ServiceImporter.CodeGenerator), names, callbackMember, callbackName, userState);
         invokeParams = new CodeExpression[4];
         this.CreateInvokeParams(invokeParams, identifier, parameters.InParameters, parameters.InCheckSpecifiedCount);
         invokeParams[2] = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), callbackMember);
         invokeParams[3] = new CodeArgumentReferenceExpression(userState);
         invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "InvokeAsync", invokeParams);
         method4.Statements.Add(invoke);
         bool methodHasOutParameters = (parameters.Return != null) || (parameters.OutParameters.Count > 0);
         WebCodeGenerator.AddCallbackImplementation(base.CodeTypeDeclaration, callbackName, handlerName, info.handlerArgs, methodHasOutParameters);
         if (base.ExportContext[str8] != null)
         {
             return codeMethod;
         }
         WebCodeGenerator.AddDelegate(base.ExtraCodeClasses, info.handlerType, methodHasOutParameters ? info.handlerArgs : typeof(AsyncCompletedEventArgs).FullName);
         if (methodHasOutParameters)
         {
             int num5 = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount;
             string[] strArray8 = new string[num5 + 1];
             SoapParameter.GetTypeFullNames(parameters.OutParameters, strArray8, 1, parameters.OutCheckSpecifiedCount, base.ServiceImporter.CodeGenerator);
             strArray8[0] = (parameters.Return == null) ? null : WebCodeGenerator.FullTypeName(parameters.Return, base.ServiceImporter.CodeGenerator);
             string[] strArray9 = new string[num5 + 1];
             SoapParameter.GetNames(parameters.OutParameters, strArray9, 1, parameters.OutCheckSpecifiedCount);
             strArray9[0] = (parameters.Return == null) ? null : "Result";
             base.ExtraCodeClasses.Add(WebCodeGenerator.CreateArgsClass(info.handlerArgs, strArray8, strArray9, base.ServiceImporter.CodeGenerator.Supports(GeneratorSupport.PartialTypes)));
         }
         base.ExportContext[str8] = info;
     }
     return codeMethod;
 }
        /// <include file='doc\SoapProtocolImporter.uex' path='docs/doc[@for="SoapProtocolImporter.GenerateMethod"]/*' />
        /// <devdoc>
        ///    <para>[To be supplied.]</para>
        /// </devdoc>
        protected override CodeMemberMethod GenerateMethod() {
            Message requestMessage;
            Message responseMessage;
            string[] parameterOrder;
            SoapBodyBinding soapRequestBinding;
            SoapBodyBinding soapResponseBinding;
            MessageBinding requestBinding;
            MessageBinding responseBinding;

            SoapOperationBinding soapOperationBinding = (SoapOperationBinding)this.OperationBinding.Extensions.Find(typeof(SoapOperationBinding));
            if (soapOperationBinding == null) throw OperationBindingSyntaxException(Res.GetString(Res.MissingSoapOperationBinding0));

            SoapBindingStyle soapBindingStyle = soapOperationBinding.Style;
            if (soapBindingStyle == SoapBindingStyle.Default)
                soapBindingStyle = SoapBinding.Style;
            if (soapBindingStyle == SoapBindingStyle.Default)
                soapBindingStyle = SoapBindingStyle.Document;

            parameterOrder = this.Operation.ParameterOrder;

            requestMessage = this.InputMessage;
            requestBinding = this.OperationBinding.Input;
            soapRequestBinding = (SoapBodyBinding)this.OperationBinding.Input.Extensions.Find(typeof(SoapBodyBinding));
            if (soapRequestBinding == null) {
                UnsupportedOperationBindingWarning(Res.GetString(Res.MissingSoapBodyInputBinding0));
                return null;
            }

            if (this.Operation.Messages.Output != null) {
                responseMessage = this.OutputMessage;
                responseBinding = this.OperationBinding.Output;
                soapResponseBinding = (SoapBodyBinding)this.OperationBinding.Output.Extensions.Find(typeof(SoapBodyBinding));
                if (soapResponseBinding == null) {
                    UnsupportedOperationBindingWarning(Res.GetString(Res.MissingSoapBodyOutputBinding0));
                    return null;
                }
            }
            else {
                responseMessage = null;
                responseBinding = null;
                soapResponseBinding = null;
            }

            CodeAttributeDeclarationCollection metadata = new CodeAttributeDeclarationCollection();

            PrepareHeaders(requestBinding);
            if (responseBinding != null) PrepareHeaders(responseBinding);

            string requestMessageName;
            string responseMessageName = null;

            requestMessageName = !String.IsNullOrEmpty(requestBinding.Name) && soapBindingStyle != SoapBindingStyle.Rpc ? requestBinding.Name : this.Operation.Name; // per WSDL 1.1 sec 3.5
            requestMessageName = XmlConvert.DecodeName(requestMessageName);

            if (responseBinding != null) {
                responseMessageName = !String.IsNullOrEmpty(responseBinding.Name) && soapBindingStyle != SoapBindingStyle.Rpc ? responseBinding.Name : this.Operation.Name + "Response"; // per WSDL 1.1 sec 3.5
                responseMessageName = XmlConvert.DecodeName(responseMessageName);
            }

            GenerateExtensionMetadata(metadata);
            GenerateHeaders(metadata, soapRequestBinding.Use, soapBindingStyle == SoapBindingStyle.Rpc, requestBinding, responseBinding);

            MessagePart[] requestParts = GetMessageParts(requestMessage, soapRequestBinding);
            bool hasWrapper;
            if (!CheckMessageStyles(MethodName, requestParts, soapRequestBinding, soapBindingStyle, out hasWrapper))
                return null;

            MessagePart[] responseParts = null;
            if (responseMessage != null) {
                responseParts = GetMessageParts(responseMessage, soapResponseBinding);
                bool responseHasWrapper;
                if (!CheckMessageStyles(MethodName, responseParts, soapResponseBinding, soapBindingStyle, out responseHasWrapper)) 
                    return null;

                // since we're using a potentially inaccurate heuristic to determine whether there's a wrapper,
                // if we disagree about the request and response we should assume there isn't a wrapper.
                if (hasWrapper != responseHasWrapper)
                    hasWrapper = false;
            }

            bool wrapperNamesMatter = (soapBindingStyle != SoapBindingStyle.Rpc && hasWrapper) || (soapRequestBinding.Use == SoapBindingUse.Literal && soapBindingStyle == SoapBindingStyle.Rpc);

            XmlMembersMapping request = ImportMessage(requestMessageName, requestParts, soapRequestBinding, soapBindingStyle, hasWrapper);
            if (request == null) return null;

            XmlMembersMapping response = null;

            if (responseMessage != null) {
                response = ImportMessage(responseMessageName, responseParts, soapResponseBinding, soapBindingStyle, hasWrapper);
                if (response == null) return null;
            }

            string methodName = CodeIdentifier.MakeValid(XmlConvert.DecodeName(this.Operation.Name));
            if (ClassName == methodName) {
                methodName = "Call" + methodName;
            }
            string uniqueMethodName = MethodNames.AddUnique(CodeIdentifier.MakeValid(XmlConvert.DecodeName(methodName)), this.Operation);
            bool differentNames = methodName != uniqueMethodName;

            CodeIdentifiers localIdentifiers = new CodeIdentifiers(false);
            localIdentifiers.AddReserved(uniqueMethodName);

            SoapParameters parameters = new SoapParameters(request, response, parameterOrder, MethodNames);

            foreach (SoapParameter param in parameters.Parameters) {
                if ((param.IsOut || param.IsByRef) && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReferenceParameters)) {
                    UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportReferenceParameters, ServiceImporter.CodeGenerator.GetType().Name));
                    return null;
                }
                param.name = localIdentifiers.AddUnique(param.name, null);
                if (param.mapping.CheckSpecified)
                    param.specifiedName = localIdentifiers.AddUnique(param.name + "Specified", null);
            }

            if (!(Style == ServiceDescriptionImportStyle.Client) || differentNames) {
                BeginMetadata();
                if (differentNames) AddMetadataProperty("MessageName", uniqueMethodName);
                EndMetadata(metadata, typeof(WebMethodAttribute), null);
            }

            BeginMetadata();
            if (wrapperNamesMatter && request.ElementName.Length > 0 && request.ElementName != uniqueMethodName)
                AddMetadataProperty("RequestElementName", request.ElementName);
            if (request.Namespace != null)
                AddMetadataProperty("RequestNamespace", request.Namespace);
            if (response == null) {
                AddMetadataProperty("OneWay", true);                    
            }
            else {
                if (wrapperNamesMatter && response.ElementName.Length > 0 && response.ElementName != (uniqueMethodName + "Response"))
                    AddMetadataProperty("ResponseElementName", response.ElementName);
                if (response.Namespace != null)
                    AddMetadataProperty("ResponseNamespace", response.Namespace);                                     
            }

            if (soapBindingStyle == SoapBindingStyle.Rpc) {
                if (soapRequestBinding.Use != SoapBindingUse.Encoded) {
                    AddMetadataProperty("Use", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapRequestBinding.Use, "G")));
                }
                EndMetadata(metadata, typeof(SoapRpcMethodAttribute), soapOperationBinding.SoapAction);
            }
            else {
                AddMetadataProperty("Use", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapBindingUse).FullName), Enum.Format(typeof(SoapBindingUse), soapRequestBinding.Use, "G")));
                AddMetadataProperty("ParameterStyle", new CodeFieldReferenceExpression(new CodeTypeReferenceExpression(typeof(SoapParameterStyle).FullName), Enum.Format(typeof(SoapParameterStyle), hasWrapper ? SoapParameterStyle.Wrapped : SoapParameterStyle.Bare, "G")));
                EndMetadata(metadata, typeof(SoapDocumentMethodAttribute), soapOperationBinding.SoapAction);
            }
            IsEncodedBinding = IsEncodedBinding || (soapRequestBinding.Use == SoapBindingUse.Encoded);

            CodeAttributeDeclarationCollection[] paramsMetadata = new CodeAttributeDeclarationCollection[parameters.Parameters.Count + parameters.CheckSpecifiedCount];
            int j = 0;
            CodeAttributeDeclaration ignoreAttribute = new CodeAttributeDeclaration(typeof(XmlIgnoreAttribute).FullName);
            foreach (SoapParameter parameter in parameters.Parameters) {
                paramsMetadata[j] = new CodeAttributeDeclarationCollection();
                if (soapRequestBinding.Use == SoapBindingUse.Encoded)
                    soapExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping, parameter.name != parameter.mapping.MemberName);
                else {
                    string ns = soapBindingStyle == SoapBindingStyle.Rpc ? parameter.mapping.Namespace : parameter.IsOut ? response.Namespace : request.Namespace;
                    bool forceUseMemberName = parameter.name != parameter.mapping.MemberName;
                    xmlExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping,  ns, forceUseMemberName);
                    if (parameter.mapping.CheckSpecified) {
                        j++;
                        paramsMetadata[j] = new CodeAttributeDeclarationCollection();
                        xmlExporter.AddMappingMetadata(paramsMetadata[j], parameter.mapping, ns, parameter.specifiedName != parameter.mapping.MemberName + "Specified");
                        paramsMetadata[j].Add(ignoreAttribute);
                    }
                }
                if (paramsMetadata[j].Count > 0  && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ParameterAttributes)) {
                    UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportParameterAttributes, ServiceImporter.CodeGenerator.GetType().Name));
                    return null;
                }
                j++;
            }

            CodeFlags[] parameterFlags = SoapParameter.GetCodeFlags(parameters.Parameters, parameters.CheckSpecifiedCount);
            string[] parameterTypes = SoapParameter.GetTypeFullNames(parameters.Parameters, parameters.CheckSpecifiedCount, ServiceImporter.CodeGenerator);
            string returnType = parameters.Return == null ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator);

            CodeMemberMethod mainCodeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, methodName, 
                                        parameterFlags, 
                                        parameterTypes,
                                        SoapParameter.GetNames(parameters.Parameters, parameters.CheckSpecifiedCount),
                                        paramsMetadata,
                                        returnType,
                                        metadata, 
                                        CodeFlags.IsPublic | (Style == ServiceDescriptionImportStyle.Client ? 0 : CodeFlags.IsAbstract));

            mainCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true));

            if (parameters.Return != null) {
                if (soapRequestBinding.Use == SoapBindingUse.Encoded)
                    soapExporter.AddMappingMetadata(mainCodeMethod.ReturnTypeCustomAttributes, parameters.Return, parameters.Return.ElementName != uniqueMethodName + "Result");
                else
                    xmlExporter.AddMappingMetadata(mainCodeMethod.ReturnTypeCustomAttributes, parameters.Return, response.Namespace, parameters.Return.ElementName != uniqueMethodName + "Result");

                if (mainCodeMethod.ReturnTypeCustomAttributes.Count != 0 && !ServiceImporter.CodeGenerator.Supports(GeneratorSupport.ReturnTypeAttributes)) {
                    UnsupportedOperationWarning(Res.GetString(Res.CodeGenSupportReturnTypeAttributes, ServiceImporter.CodeGenerator.GetType().Name));
                    return null;
                }
            }

            string resultsName = localIdentifiers.MakeUnique("results");

            if (Style == ServiceDescriptionImportStyle.Client) {
                bool oldAsync = (ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateOldAsync) != 0;
                bool newAsync = (ServiceImporter.CodeGenerationOptions & CodeGenerationOptions.GenerateNewAsync) != 0 && 
                    ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareEvents) && 
                    ServiceImporter.CodeGenerator.Supports(GeneratorSupport.DeclareDelegates);
                CodeExpression[] invokeParams = new CodeExpression[2];
                CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount);
                CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "Invoke", invokeParams);
                WriteReturnMappings(mainCodeMethod, invoke, parameters, resultsName);

                if (oldAsync) {
                    int inCount = parameters.InParameters.Count + parameters.InCheckSpecifiedCount;

                    string[] asyncParameterTypes = new string[inCount + 2];
                    SoapParameter.GetTypeFullNames(parameters.InParameters, asyncParameterTypes, 0, parameters.InCheckSpecifiedCount, ServiceImporter.CodeGenerator);
                    asyncParameterTypes[inCount] = typeof(AsyncCallback).FullName;
                    asyncParameterTypes[inCount + 1] = typeof(object).FullName;

                    string[] asyncParameterNames = new string[inCount + 2];
                    SoapParameter.GetNames(parameters.InParameters, asyncParameterNames, 0, parameters.InCheckSpecifiedCount);
                    asyncParameterNames[inCount] = "callback";
                    asyncParameterNames[inCount + 1] = "asyncState";

                    CodeFlags[] asyncParameterFlags = new CodeFlags[inCount + 2];

                    CodeMemberMethod beginCodeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, "Begin" + uniqueMethodName, 
                        asyncParameterFlags,
                        asyncParameterTypes, 
                        asyncParameterNames, 
                        typeof(IAsyncResult).FullName, 
                        null, 
                        CodeFlags.IsPublic);

                    beginCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true));

                    invokeParams = new CodeExpression[4];
                    CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount);
                    invokeParams[2] = new CodeArgumentReferenceExpression("callback");
                    invokeParams[3] = new CodeArgumentReferenceExpression("asyncState");

                    invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "BeginInvoke", invokeParams);
                    beginCodeMethod.Statements.Add(new CodeMethodReturnStatement(invoke));

                    int outCount = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount;
                    string[] asyncReturnTypes = new string[outCount + 1];
                    SoapParameter.GetTypeFullNames(parameters.OutParameters, asyncReturnTypes, 1, parameters.OutCheckSpecifiedCount, ServiceImporter.CodeGenerator);
                    asyncReturnTypes[0] = typeof(IAsyncResult).FullName;

                    string[] asyncReturnNames = new string[outCount + 1];
                    SoapParameter.GetNames(parameters.OutParameters, asyncReturnNames, 1, parameters.OutCheckSpecifiedCount);
                    asyncReturnNames[0] = "asyncResult";

                    CodeFlags[] asyncReturnFlags = new CodeFlags[outCount + 1];
                    for (int i = 0; i < outCount; i++)
                        asyncReturnFlags[i + 1] = CodeFlags.IsOut;

                    CodeMemberMethod codeMethod = WebCodeGenerator.AddMethod(this.CodeTypeDeclaration, "End" + uniqueMethodName, 
                        asyncReturnFlags, 
                        asyncReturnTypes, 
                        asyncReturnNames, 
                        parameters.Return == null ? typeof(void).FullName : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator), 
                        null, 
                        CodeFlags.IsPublic);

                    codeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true));

                    CodeExpression invokeParam = new CodeArgumentReferenceExpression("asyncResult");
                    invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "EndInvoke", new CodeExpression[] { invokeParam });

                    WriteReturnMappings(codeMethod, invoke, parameters, resultsName);
                }

                // new RAD Async pattern
                if (newAsync) {
                    string methodKey = MethodSignature(uniqueMethodName, returnType, parameterFlags, parameterTypes);
                    DelegateInfo delegateInfo = (DelegateInfo)ExportContext[methodKey];
                    if (delegateInfo == null) {
                        string handlerType = ClassNames.AddUnique(uniqueMethodName + "CompletedEventHandler", uniqueMethodName);
                        string handlerArgs = ClassNames.AddUnique(uniqueMethodName + "CompletedEventArgs", uniqueMethodName);
                        delegateInfo = new DelegateInfo(handlerType, handlerArgs);
                    }
                    string handlerName = MethodNames.AddUnique(uniqueMethodName + "Completed", uniqueMethodName);
                    string asyncName = MethodNames.AddUnique(uniqueMethodName + "Async", uniqueMethodName);
                    string callbackMember = MethodNames.AddUnique(uniqueMethodName + "OperationCompleted", uniqueMethodName);
                    string callbackName = MethodNames.AddUnique("On" + uniqueMethodName + "OperationCompleted", uniqueMethodName);

                    // public event xxxCompletedEventHandler xxxCompleted;
                    WebCodeGenerator.AddEvent(this.CodeTypeDeclaration.Members, delegateInfo.handlerType, handlerName);

                    // private SendOrPostCallback xxxOperationCompleted;
                    WebCodeGenerator.AddCallbackDeclaration(this.CodeTypeDeclaration.Members, callbackMember);

                    // create the pair of xxxAsync methods
                    string[] inParamNames = SoapParameter.GetNames(parameters.InParameters, parameters.InCheckSpecifiedCount);
                    string userState = UniqueName("userState", inParamNames);
                    CodeMemberMethod asyncCodeMethod = WebCodeGenerator.AddAsyncMethod(this.CodeTypeDeclaration, asyncName, 
                        SoapParameter.GetTypeFullNames(parameters.InParameters, parameters.InCheckSpecifiedCount, ServiceImporter.CodeGenerator), inParamNames, callbackMember, callbackName, userState);

                    // Generate InvokeAsync call
                    invokeParams = new CodeExpression[4];
                    CreateInvokeParams(invokeParams, uniqueMethodName, parameters.InParameters, parameters.InCheckSpecifiedCount);
                    invokeParams[2] = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), callbackMember);
                    invokeParams[3] = new CodeArgumentReferenceExpression(userState);
                        
                    invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "InvokeAsync", invokeParams);
                    asyncCodeMethod.Statements.Add(invoke);

                    //  private void On_xxx_OperationCompleted(object arg) {..}
                    bool methodHasOutParameters = parameters.Return != null || parameters.OutParameters.Count > 0;
                    WebCodeGenerator.AddCallbackImplementation(this.CodeTypeDeclaration, callbackName, handlerName, delegateInfo.handlerArgs, methodHasOutParameters);

                    if (ExportContext[methodKey] == null) {
                        // public delegate void xxxCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs args);
                        WebCodeGenerator.AddDelegate(ExtraCodeClasses, delegateInfo.handlerType, methodHasOutParameters ? delegateInfo.handlerArgs : typeof(AsyncCompletedEventArgs).FullName);
                        
                        // Create strongly-typed Args class
                        if (methodHasOutParameters) {
                            int outCount = parameters.OutParameters.Count + parameters.OutCheckSpecifiedCount;
                            string[] asyncReturnTypes = new string[outCount + 1];
                            SoapParameter.GetTypeFullNames(parameters.OutParameters, asyncReturnTypes, 1, parameters.OutCheckSpecifiedCount, ServiceImporter.CodeGenerator);
                            asyncReturnTypes[0] = parameters.Return == null ? null : WebCodeGenerator.FullTypeName(parameters.Return, ServiceImporter.CodeGenerator);

                            string[] asyncReturnNames = new string[outCount + 1];
                            SoapParameter.GetNames(parameters.OutParameters, asyncReturnNames, 1, parameters.OutCheckSpecifiedCount);
                            asyncReturnNames[0] = parameters.Return == null ? null : "Result";
                            ExtraCodeClasses.Add(WebCodeGenerator.CreateArgsClass(delegateInfo.handlerArgs, asyncReturnTypes, asyncReturnNames, ServiceImporter.CodeGenerator.Supports(GeneratorSupport.PartialTypes)));
                        }
                        ExportContext[methodKey] = delegateInfo;
                    }
                }
            }
            return mainCodeMethod;
        }