private CodeMemberMethod BuildClientProxyMethod(ServiceOp serviceOp, IList <Message> messages, MessageEncodingType encodingType)
        {
            string reqElementName       = null;
            string reqTypeName          = null;
            string reqElementNamespace  = null;
            string respElementName      = null;
            string respTypeName         = null;
            string respElementNamespace = null;

            foreach (Message message in messages)
            {
                if (serviceOp.Operation.Messages.Input != null && serviceOp.Operation.Messages.Input.Message.Name == message.Name)
                {
                    if (message.Parts.Count != 0)
                    {
                        reqElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                        reqTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                        reqElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                    }
                }
                else if (serviceOp.Operation.Messages.Output != null && serviceOp.Operation.Messages.Output.Message.Name == message.Name)
                {
                    if (message.Parts.Count != 0)
                    {
                        respElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                        respTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                        respElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                    }
                }
            }

            // If either element name is null set to default for serializer naming
            reqElementName  = reqElementName == null ? serviceOp.Operation.Name + "Request" : reqElementName;
            respElementName = respElementName == null ? serviceOp.Operation.Name + "Response" : respElementName;

            // If either type name is null set to default "void"
            reqTypeName  = reqTypeName == null ? "void" : reqTypeName;
            respTypeName = respTypeName == null ? "void" : respTypeName;

            // Set the method name from Action.
            string methodName = serviceOp.InAction;

            if (methodName == null)
            {
                methodName = serviceOp.Operation.Name;
            }
            else
            {
                int index = methodName.LastIndexOfAny(new char[] { ':', '/', '\\' });
                methodName = (index == -1 || index == (methodName.Length - 1)) ? methodName : methodName.Substring(index + 1);
            }

            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Name       = methodName;
            codeMethod.Attributes = MemberAttributes.Public;
            if (respTypeName != "void")
            {
                codeMethod.ReturnType = new CodeTypeReference(respTypeName);
            }
            else
            {
                codeMethod.ReturnType = new CodeTypeReference(typeof(void));
            }

            if (reqTypeName != "void")
            {
                codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(reqTypeName, "req"));
            }

            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Create request header"));
            // Generated Code: string action;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "String",
                    "action"
                    )
                );
            // Generated Code: action = "http://www.nrf-arts.org/IXRetail/namespace/PosPrinter/EventName";
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("action"),
                    new CodePrimitiveExpression(serviceOp.InAction)
                    )
                );
            // Generated Code: WsWsaHeader header;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "WsWsaHeader",
                    "header"
                    )
                );
            // Generated Code: header = new WsWsaHeader(action, null, EndpointAddress, m_version.AnonymousUri, null, null);
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("header"),
                    new CodeObjectCreateExpression(
                        "WsWsaHeader",
                        new CodeExpression[] {
                new CodeVariableReferenceExpression("action"),
                new CodePrimitiveExpression(null),
                new CodeVariableReferenceExpression("EndpointAddress"),
                new CodeFieldReferenceExpression(
                    new CodeVariableReferenceExpression("m_version"), "AnonymousUri"),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
            }
                        )
                    )
                );

            CodeExpression obj;

            if (reqTypeName != "void")
            {
                obj = new CodeVariableReferenceExpression("req");
            }
            else
            {
                obj = new CodePrimitiveExpression(null);
            }

            // Generated Code:  WsMessage request = new WsMessage(header, req, WsPrefix.None);
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement("WsMessage", "request",
                                                     new CodeObjectCreateExpression(
                                                         "WsMessage",
                                                         new CodeVariableReferenceExpression("header"),
                                                         obj,
                                                         new CodeFieldReferenceExpression(
                                                             new CodeVariableReferenceExpression("WsPrefix"),
                                                             "None"
                                                             )
                                                         )
                                                     )
                );

            // If message body is empty skip request seralizer
            if (reqTypeName != "void")
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Create request serializer"));
                // requestTypeNameDataContractSerializer eventDcs;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        CodeGenUtils.GenerateDcsName(reqTypeName),
                        "reqDcs"
                        )
                    );
                // reqDcs = new requestTypeNameDataContractSerializer("reqTypeName", ServiceNamespace.Namespace);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("reqDcs"),
                        new CodeObjectCreateExpression(
                            CodeGenUtils.GenerateDcsName(reqTypeName),
                            new CodeExpression[] {
                    new CodePrimitiveExpression(reqElementName),
                    new CodePrimitiveExpression(reqElementNamespace)
                }
                            )
                        )
                    );

                // Generated Code: request.Serializer = reqDcs;
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("request"), "Serializer"),
                        new CodeVariableReferenceExpression("reqDcs")
                        )
                    );
            }

            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("request"), "Method"),
                    new CodePrimitiveExpression(methodName)
                    )
                );



            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            //codeMethod.Statements.Add(new CodeCommentStatement("Build soap request message"));
            //// Generated Code: byte[] soapBuffer = SoapMessageBuilder.BuildSoapMessage(header, reqDcs, req);
            //CodeExpression reqDcsParam;
            //CodeExpression reqParam;
            //if (reqTypeName == "void")
            //{
            //    reqDcsParam = new CodePrimitiveExpression(null);
            //    reqParam = new CodePrimitiveExpression(null);
            //}
            //else
            //{
            //    reqDcsParam = new CodeVariableReferenceExpression("reqDcs");
            //    reqParam = new CodeVariableReferenceExpression("req");
            //}

            //codeMethod.Statements.Add(
            //    new CodeVariableDeclarationStatement(
            //        typeof(byte[]),
            //        "soapBuffer",
            //        new CodeMethodInvokeExpression(
            //            new CodeVariableReferenceExpression("SoapMessageBuilder"),
            //            "BuildSoapMessage",
            //            new CodeExpression[] {
            //                new CodeVariableReferenceExpression("header"),
            //                reqDcsParam,
            //                reqParam
            //            }
            //        )
            //    )
            //);

            // If this is an mtom message create body parts collection
            // If the message encoding is Mtom set the mtom encoded flag
            if (encodingType == MessageEncodingType.Mtom)
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Indicate that this message will use Mtom encoding"));
                // Generated Code: request.BodyParts = new WsMtomBodyParts();
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("request"), "BodyParts"),
                        new CodeObjectCreateExpression("WsMtomBodyParts")
                        )
                    );


                //codeMethod.Statements.Add(new CodeCommentStatement("Build mtom request message and store as first Mtom Bodypart"));
                //// Generated Code: MessageType = WsMessageType.Mtom;
                //codeMethod.Statements.Add(
                //    new CodeAssignStatement(
                //        new CodeVariableReferenceExpression("MessageType"),
                //        new CodeFieldReferenceExpression(
                //            new CodeVariableReferenceExpression("WsMessageType"),
                //            "Mtom"
                //        )
                //    )
                //);
                // WsMtomBodyParts bodyParts = new WsMtomBodyParts();
                //codeMethod.Statements.Add(
                //    new CodeVariableDeclarationStatement("WsMtomBodyParts",
                //        "bodyParts",
                //        new CodeObjectCreateExpression("WsMtomBodyParts", new CodeExpression[] {})
                //    )
                //);
                //// Generated Code: bodyParts.Start = "<soap@soap>";
                //codeMethod.Statements.Add(
                //    new CodeAssignStatement(
                //        new CodeFieldReferenceExpression(
                //            new CodeVariableReferenceExpression("bodyParts"),
                //            "Start"
                //        ),
                //        new CodePrimitiveExpression("<soap@soap>")
                //    )
                //);
                //// bodyParts.Add(respDcs.CreateNewBodyPart(soapBuffer, "soap@soap"));
                //codeMethod.Statements.Add(
                //    new CodeMethodInvokeExpression(
                //        new CodeVariableReferenceExpression("bodyParts"),
                //        "Add",
                //        new CodeExpression[] {
                //            new CodeMethodInvokeExpression(
                //                new CodeVariableReferenceExpression("reqDcs"),
                //                "CreateNewBodyPart",
                //                new CodeExpression[] {
                //                    new CodeVariableReferenceExpression("soapBuffer"),
                //                    new CodePrimitiveExpression("<soap@soap>")
                //                }
                //            )
                //        }
                //    )
                //);
                //// bodyParts.Add(reqDcs.BodyParts[0]);
                //codeMethod.Statements.Add(
                //    new CodeMethodInvokeExpression(
                //        new CodeVariableReferenceExpression("bodyParts"),
                //        "Add",
                //        new CodeExpression[] {
                //            new CodeIndexerExpression(
                //                new CodeFieldReferenceExpression(
                //                    new CodeVariableReferenceExpression("reqDcs"),
                //                    "BodyParts"
                //                ),
                //                new CodeExpression[] {
                //                    new CodePrimitiveExpression(0)
                //                }
                //            )
                //        }
                //    )
                //);
            }
            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Send service request"));

            // Generated Code: DpwsSoapResponse response;
            //codeMethod.Statements.Add(
            //    new CodeVariableDeclarationStatement("DpwsSoapResponse", "response")
            //);
            //// Depending on whether this is an mtom request or not
            //// Generated Code: response = m_httpClient.SendRequest(BodyParts, SimpleService, true, false);
            //// or
            //// Generated Code: response = m_httpClient.SendRequest(soapBuffer, SimpleService, true, false);
            //codeMethod.Statements.Add(
            //    new CodeAssignStatement(
            //        new CodeVariableReferenceExpression("response"),
            //        new CodeMethodInvokeExpression(
            //            new CodeVariableReferenceExpression("m_httpClient"),
            //            "SendRequest",
            //            new CodeExpression[] {
            //                new CodeVariableReferenceExpression(encodingType == MessageEncodingType.Mtom ? "ref bodyParts" : "soapBuffer"),
            //                new CodeVariableReferenceExpression("EndpointAddress"),
            //                new CodePrimitiveExpression(serviceOp.Operation.Messages.Flow == OperationFlow.OneWay || respTypeName == "void" ? true : false),
            //                new CodePrimitiveExpression(false)
            //            }
            //        )
            //    )
            //);

            // Generated Code: m_requestChannel.Open();
            codeMethod.Statements.Add(
                new CodeMethodInvokeExpression(
                    new CodeVariableReferenceExpression("m_requestChannel"),
                    "Open"
                    )
                );

            if (serviceOp.Operation.Messages.Flow == OperationFlow.OneWay || (respTypeName == "void"))
            {
                // Generated Code: m_requestChannel.RequestOneWay(request);
                codeMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("m_requestChannel"),
                        "RequestOneWay",
                        new CodeVariableReferenceExpression("request")
                        )
                    );
            }
            else
            {
                // Generated Code: WsMessage response = m_requestChannel.Request(request);

                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement("WsMessage", "response",
                                                         new CodeMethodInvokeExpression(
                                                             new CodeVariableReferenceExpression("m_requestChannel"),
                                                             "Request",
                                                             new CodeVariableReferenceExpression("request")
                                                             )
                                                         )
                    );
            }

            // Generated Code: m_requestChannel.Open();
            codeMethod.Statements.Add(
                new CodeMethodInvokeExpression(
                    new CodeVariableReferenceExpression("m_requestChannel"),
                    "Close"
                    )
                );


            if (serviceOp.Operation.Messages.Flow == OperationFlow.RequestResponse || serviceOp.Operation.Messages.Flow == OperationFlow.RequestResponse)
            {
                if (respTypeName != "void")
                {
                    codeMethod.Statements.Add(new CodeSnippetStatement(""));
                    codeMethod.Statements.Add(new CodeCommentStatement("Process response"));
                    // Generated Code: TwoWayResponseDataContractSerializer respDcs;
                    codeMethod.Statements.Add(
                        new CodeVariableDeclarationStatement(
                            CodeGenUtils.GenerateDcsName(respTypeName),
                            "respDcs"
                            )
                        );
                    // Generated Code: respDcs = new ResponseDataTypeNameDataContractSerializer("ResponseDataTypeName", "http://schemas.example.org/SimpleService");
                    codeMethod.Statements.Add(
                        new CodeAssignStatement(
                            new CodeVariableReferenceExpression("respDcs"),
                            new CodeObjectCreateExpression(
                                CodeGenUtils.GenerateDcsName(respTypeName),
                                new CodeExpression[] {
                        new CodePrimitiveExpression(respElementName),
                        new CodePrimitiveExpression(respElementNamespace)
                    }
                                )
                            )
                        );

                    // If the encoding type is mtom copy the body parts content to the response object
                    if (encodingType == MessageEncodingType.Mtom)
                    {
                        // respDcs.BodyParts = bodyParts;
                        codeMethod.Statements.Add(
                            new CodeAssignStatement(
                                new CodeFieldReferenceExpression(
                                    new CodeVariableReferenceExpression("respDcs"),
                                    "BodyParts"
                                    ),
                                new CodeFieldReferenceExpression(
                                    new CodeVariableReferenceExpression("response"),
                                    "BodyParts"
                                    )
                                //new CodeVariableReferenceExpression("bodyParts")
                                )
                            );
                    }

                    // Generated Code: TwoWayResponse resp;
                    codeMethod.Statements.Add(
                        new CodeVariableDeclarationStatement(respTypeName, "resp")
                        );
                    // Generated Code: resp = (TwoWayResponse)respDcs.ReadObject(response.Reader);
                    codeMethod.Statements.Add(
                        new CodeAssignStatement(
                            new CodeVariableReferenceExpression("resp"),
                            new CodeCastExpression(
                                respTypeName,
                                new CodeMethodInvokeExpression(
                                    new CodeVariableReferenceExpression("respDcs"),
                                    "ReadObject",
                                    new CodeExpression[] {
                        new CodeFieldReferenceExpression(
                            new CodeVariableReferenceExpression("response"),
                            "Reader"
                            )
                    }
                                    )
                                )
                            )
                        );

                    // Add response.Reader.Dispose() method call
                    codeMethod.Statements.Add(
                        new CodeMethodInvokeExpression(
                            new CodeFieldReferenceExpression(
                                new CodeVariableReferenceExpression("response"),
                                "Reader"
                                ),
                            "Dispose", new CodeExpression[] { }
                            )
                        );

                    // reqest.Reader = null;
                    codeMethod.Statements.Add(
                        new CodeAssignStatement(
                            new CodeFieldReferenceExpression(
                                new CodeVariableReferenceExpression("response"),
                                "Reader"
                                ),
                            new CodePrimitiveExpression(null)
                            )
                        );

                    // return resp;
                    codeMethod.Statements.Add(
                        new CodeMethodReturnStatement(
                            new CodeVariableReferenceExpression("resp")
                            )
                        );
                }
                else
                {
                    // return null;
                    codeMethod.Statements.Add(
                        new CodeMethodReturnStatement()
                        );
                }
            }

            return(codeMethod);
        }
        public void AddOperation(Operation operation, string inAction, string outAction)
        {
            ServiceOp serviceOp = new ServiceOp(operation, inAction, outAction);

            m_operations.Add(serviceOp);
        }
        private CodeMemberMethod BuildEventSource(ServiceOp serviceOp, IList <Message> messages)
        {
            string reqElementName      = null;
            string reqTypeName         = null;
            string reqElementNamespace = null;

            foreach (Message message in messages)
            {
                if (serviceOp.Operation.Messages.Output != null && serviceOp.Operation.Messages.Output.Message.Name == message.Name)
                {
                    reqTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                    reqElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                    reqElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                }
            }

            // If the element name is null set default name
            reqElementName = reqElementName == null ? serviceOp.Operation.Name + "Request" : reqElementName;

            // If the type name is null set it to the default name "void"
            reqTypeName = reqTypeName == null ? "void" : reqTypeName;

            // Set the DataContractSerailizer name prefix
            // If the type is an array in the prefix replace "[]" in the type name with "Array"
            string reqDCSPrefix;

            if (reqTypeName.Length > 2 && reqTypeName.Substring(reqTypeName.Length - 2) == "[]")
            {
                reqDCSPrefix = reqTypeName.Substring(0, reqTypeName.Length - 2) + "Array";
            }

            // Set the method name from Action. The Hosted service dispatcher maps method calls to the action endpoint
            string methodName = serviceOp.OutAction;

            if (methodName == null)
            {
                methodName = serviceOp.Operation.Name;
            }
            else
            {
                int index = methodName.LastIndexOfAny(new char[] { ':', '/', '\\' });
                methodName = (index == -1 || index == (methodName.Length - 1)) ? methodName : methodName.Substring(index + 1);
            }

            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Name       = methodName;
            codeMethod.Attributes = MemberAttributes.Public;
            codeMethod.ReturnType = new CodeTypeReference();
            if (reqTypeName != "void")
            {
                codeMethod.Parameters.Add(new CodeParameterDeclarationExpression(reqTypeName, "eventReq"));
            }

            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Create temp event source object, set the event action and create the event header"));
            // Generated Code: DpwsWseEventSource eventSource;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "DpwsWseEventSource",
                    "eventSource"
                    )
                );
            // Generated Code: eventSource = EventSources["reqTypeName"];
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("eventSource"),
                    new CodeArrayIndexerExpression(
                        new CodeVariableReferenceExpression("EventSources"),
                        new CodePrimitiveExpression(serviceOp.Operation.Name)
                        )
                    )
                );
            // Generated Code: string action;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "String",
                    "action"
                    )
                );
            // Generated Code: action = "http://www.nrf-arts.org/IXRetail/namespace/PosPrinter/EventName";
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("action"),
                    new CodePrimitiveExpression(serviceOp.OutAction)
                    )
                );
            // Generated Code: WsWsaHeader header;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "WsWsaHeader",
                    "header"
                    )
                );
            // Generated Code: header = new WsWsaHeader(action, null, null, null, null, null);
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("header"),
                    new CodeObjectCreateExpression(
                        "WsWsaHeader",
                        new CodeExpression[] {
                new CodeVariableReferenceExpression("action"),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
            }
                        )
                    )
                );

            // Generated Code: WsMessage msg = new WsMessage(header, eventReq, WsPrefix.Wse);
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement("WsMessage", "msg",
                                                     new CodeObjectCreateExpression(
                                                         "WsMessage",
                                                         new CodeExpression[] {
                new CodeVariableReferenceExpression("header"),
                new CodeVariableReferenceExpression("eventReq"),
                new CodeFieldReferenceExpression(
                    new CodeVariableReferenceExpression("WsPrefix"), "Wse"
                    )
            }
                                                         )
                                                     )
                );

            // If the event message body is empty skip serialization code
            if (reqTypeName != "void")
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Create event serializer and write the event object"));
                // eventTypeNameDataContractSerializer eventDcs;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        CodeGenUtils.GenerateDcsName(reqTypeName),
                        "eventDcs"
                        )
                    );

                // Generated Code: eventDcs = new eventTypeNameDataContractSerializer("elementTypeName", ServiceNamespace.Namespace);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("eventDcs"),
                        new CodeObjectCreateExpression(
                            CodeGenUtils.GenerateDcsName(reqTypeName),
                            new CodeExpression[] {
                    new CodePrimitiveExpression(reqElementName),
                    new CodePrimitiveExpression(reqElementNamespace)
                }
                            )
                        )
                    );

                // Generated Code: msg.Serializer = eventDcs;
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("msg"), "Serializer"),
                        new CodeVariableReferenceExpression("eventDcs")
                        )
                    );

                /*
                 * codeMethod.Statements.Add(new CodeSnippetStatement(""));
                 * codeMethod.Statements.Add(new CodeCommentStatement("Build event body message"));
                 *
                 * //Generated Code: byte[] soapBuffer = SoapMessageBuilder.BuildEventBody(header, eventDcs, eventReq);
                 * codeMethod.Statements.Add(
                 *  new CodeVariableDeclarationStatement(
                 *      typeof(byte[]),
                 *      "soapBuffer",
                 *      new CodeMethodInvokeExpression(
                 *          new CodeVariableReferenceExpression("SoapMessageBuilder"),
                 *          "BuildEventBody",
                 *          new CodeExpression[] {
                 *          new CodeVariableReferenceExpression("header"),
                 *          new CodeVariableReferenceExpression("eventDcs"),
                 *          new CodeVariableReferenceExpression("eventReq")
                 *      }
                 *      )
                 *  )
                 * );
                 */

                codeMethod.Statements.Add(new CodeSnippetStatement(""));

                /*
                 * // string soapMessage = new string(Encoding.UTF8.GetChars(soapBuffer));
                 * codeMethod.Statements.Add(
                 *  new CodeVariableDeclarationStatement(
                 *      typeof(string),
                 *      "soapMessage",
                 *      new CodeObjectCreateExpression(
                 *          typeof(string),
                 *          new CodeExpression[] {
                 *              new CodeMethodInvokeExpression(
                 *                  new CodeFieldReferenceExpression(
                 *                      new CodeVariableReferenceExpression("Encoding"),
                 *                      "UTF8"
                 *                  ),
                 *                  "GetChars",
                 *                  new CodeExpression[] {
                 *                      new CodeArgumentReferenceExpression("soapBuffer")
                 *                  }
                 *              )
                 *          }
                 *      )
                 *  )
                 * );
                 */
            }

            codeMethod.Statements.Add(new CodeCommentStatement("Fire event"));

            /*
             * // If message body is empty pass a null soapMessage to the FireEvent method
             * CodeExpression soapMessageExpression;
             * if (reqTypeName == "void")
             *  soapMessageExpression = new CodePrimitiveExpression(null);
             * else
             *  soapMessageExpression = new CodeTypeReferenceExpression("soapMessage");
             */

            //Device.SubscriptionManager.FireEvent(this, eventSource, header, soapMessage);
            codeMethod.Statements.Add(
                new CodeMethodInvokeExpression(
                    new CodeFieldReferenceExpression(
                        new CodeVariableReferenceExpression("Dpws.Device.Device"),
                        "SubscriptionManager"
                        ),
                    "FireEvent",
                    new CodeExpression[] {
                new CodeThisReferenceExpression(),
                new CodeTypeReferenceExpression("eventSource"),
                new CodeTypeReferenceExpression("msg")         //"header"),
                //soapMessageExpression
            }
                    )
                );

            return(codeMethod);
        }
        private CodeMemberMethod BuildProxyCallbackMethod(ServiceOp serviceOp, ClientProxy clientProxy)
        {
            string reqElementName      = null;
            string reqTypeName         = null;
            string reqElementNamespace = null;

            foreach (Message message in clientProxy.Messages)
            {
                if (serviceOp.Operation.Messages.Output != null && serviceOp.Operation.Messages.Output.Message.Name == message.Name)
                {
                    reqElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                    reqTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                    reqElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                    break;
                }
            }

            // If request element name is null set to default for serializer
            reqElementName = reqElementName == null ? serviceOp.Operation.Name + "Request" : reqElementName;

            // If request type null set to default "void"
            reqTypeName = reqTypeName == null ? "void" : reqTypeName;

            // Set the callback method name from Action.
            string methodName = serviceOp.OutAction;

            if (methodName == null)
            {
                methodName = serviceOp.Operation.Name;
            }
            else
            {
                int index = methodName.LastIndexOfAny(new char[] { ':', '/', '\\' });
                methodName = (index == -1 || index == (methodName.Length - 1)) ? methodName : methodName.Substring(index + 1);
            }

            // Create the callback handler method
            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Name       = methodName;
            codeMethod.Attributes = MemberAttributes.Public;
            codeMethod.ReturnType = new CodeTypeReference("WsMessage"); //"Byte", 1);
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("WsMessage", "request"));
            //codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("WsWsaHeader", "header"));
            //codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlReader", "reader"));

            // If message body is empty skip read serializer
            if (reqTypeName != "void")
            {
                codeMethod.Statements.Add(new CodeCommentStatement("Build request object"));
                // Generated Code: OperationNameDataContractSerializer reqDcs;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        CodeGenUtils.GenerateDcsName(reqTypeName),
                        "reqDcs"
                        )
                    );
                // Generated Code: reqDcs = new OperationNameDataContractSerializer("InMessagePartName", InputMessageTypeNamespace);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("reqDcs"),
                        new CodeObjectCreateExpression(
                            CodeGenUtils.GenerateDcsName(reqTypeName),
                            new CodeExpression[] {
                    new CodePrimitiveExpression(reqElementName),
                    new CodePrimitiveExpression(reqElementNamespace)
                }
                            )
                        )
                    );
            }

            // If the message is Mtom encoded set serializers Mtom body parts collection
            // req.BodyParts = this.BodyParts;
            if (clientProxy.EncodingType == MessageEncodingType.Mtom)
            {
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("reqDcs"), "BodyParts"),
                        new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "BodyParts")
                        )
                    );
            }

            if (reqTypeName != "void")
            {
                // Generated Code: InMessagePartName req;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        reqTypeName,
                        "req"
                        )
                    );
                // req = (typeName)reqDcs.ReadObject(reader);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("req"),
                        new CodeCastExpression(
                            reqTypeName,
                            new CodeMethodInvokeExpression(
                                new CodeVariableReferenceExpression("reqDcs"),
                                "ReadObject",
                                new CodeFieldReferenceExpression(
                                    new CodeVariableReferenceExpression("request"),
                                    "Reader"
                                    )
                                )
                            )
                        )
                    );
            }

            // Add request.Reader.Dispose() method call
            codeMethod.Statements.Add(
                new CodeMethodInvokeExpression(
                    new CodeFieldReferenceExpression(
                        new CodeVariableReferenceExpression("request"),
                        "Reader"
                        ),
                    "Dispose", new CodeExpression[] { }
                    )
                );

            // reqest.Reader = null;
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeFieldReferenceExpression(
                        new CodeVariableReferenceExpression("request"),
                        "Reader"
                        ),
                    new CodePrimitiveExpression(null)
                    )
                );

            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Call service operation to process request."));

            // Add OneWay call to device developer supplied service method implementation
            if (reqTypeName != "void")
            {
                // Generated Code: m_class.MethodName(req);
                codeMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("m_eventHandler"),
                        serviceOp.Operation.Name,
                        new CodeExpression[] {
                    new CodeVariableReferenceExpression("req")
                }
                        )
                    );
            }
            else
            {
                // Generated Code: m_class.MethodName();
                codeMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("m_eventHandler"),
                        serviceOp.Operation.Name,
                        new CodeExpression[] { }
                        )
                    );
            }

            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Return OneWayResponse message for event callback messages"));
            codeMethod.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("WsMessage"),
                        "CreateOneWayResponse"
                        )
                    )
                );
            return(codeMethod);
        }
        private CodeMemberMethod BuildOperation(ServiceOp serviceOp, IList <Message> messages, MessageEncodingType encodingType)
        {
            string reqTypeName          = null;
            string reqElementName       = null;
            string reqElementNamespace  = null;
            string respTypeName         = null;
            string respElementName      = null;
            string respElementNamespace = null;

            foreach (Message message in messages)
            {
                if (serviceOp.Operation.Messages.Input != null && serviceOp.Operation.Messages.Input.Message.Name == message.Name)
                {
                    if (message.Parts.Count != 0)
                    {
                        reqElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                        reqElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                        reqTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                    }
                }
                else if (serviceOp.Operation.Messages.Output != null && serviceOp.Operation.Messages.Output.Message.Name == message.Name)
                {
                    if (message.Parts.Count != 0)
                    {
                        respElementName      = CodeGenUtils.GetMessageElementName(serviceOp.Operation.PortType.ServiceDescription, message);
                        respElementNamespace = message.Parts[0].Element == null ? message.Parts[0].Type.Namespace : message.Parts[0].Element.Namespace;
                        respTypeName         = CodeGenUtils.GetMessageTypeName(serviceOp.Operation.PortType.ServiceDescription, message);
                    }
                }
            }

            // If either element type is null set to void type
            reqElementName  = reqElementName == null ? serviceOp.Operation.Name + "Request" : reqElementName;
            respElementName = respElementName == null ? serviceOp.Operation.Name + "Response" : respElementName;

            // If either type is null set to void type
            reqTypeName  = reqTypeName == null ? "void" : reqTypeName;
            respTypeName = respTypeName == null ? "void" : respTypeName;

            // Set the method name from Action. The Hosted service dispatcher maps method calls to the action endpoint
            string methodName = serviceOp.InAction;

            if (methodName == null)
            {
                methodName = serviceOp.Operation.Name;
            }
            else
            {
                int index = methodName.LastIndexOfAny(new char[] { ':', '/', '\\' });
                methodName = (index == -1 || index == (methodName.Length - 1)) ? methodName : methodName.Substring(index + 1);
            }

            // Create the operation member
            CodeMemberMethod codeMethod = new CodeMemberMethod();

            codeMethod.Name       = methodName;
            codeMethod.Attributes = MemberAttributes.Public;
            codeMethod.ReturnType = new CodeTypeReference("WsMessage"); //"Byte", 1);
            codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("WsMessage", "request"));
            //codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("WsWsaHeader", "header"));
            //codeMethod.Parameters.Add(new CodeParameterDeclarationExpression("XmlReader", "reader"));

            // If there is a request object (i.e. not void) create an instance of the request serializer
            if (reqTypeName != "void")
            {
                codeMethod.Statements.Add(new CodeCommentStatement("Build request object"));
                // Generated Code: TypeNameDataContractSerializer reqDcs;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        CodeGenUtils.GenerateDcsName(reqTypeName),
                        "reqDcs"
                        )
                    );
                // Generated Code: reqDcs = new TypeNameDataContractSerializer("InMessagePartName", InputMessageTypeNamespace);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("reqDcs"),
                        new CodeObjectCreateExpression(
                            CodeGenUtils.GenerateDcsName(reqTypeName),
                            new CodeExpression[] {
                    new CodePrimitiveExpression(reqElementName),
                    new CodePrimitiveExpression(reqElementNamespace)
                }
                            )
                        )
                    );
            }
            // If the message is Mtom encoded set serializers Mtom body parts collection
            // req.BodyParts = this.BodyParts;
            if (encodingType == MessageEncodingType.Mtom)
            {
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("reqDcs"), "BodyParts"),
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("request"), "BodyParts")
                        )
                    );
            }
            // If there is a request object (i.e. not void) create it and set it.
            if (reqTypeName != "void")
            {
                // Generated Code: InMessagePartName req;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        reqTypeName,
                        "req"
                        )
                    );
                // req = reqDcs.ReadObject(reader);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("req"),
                        new CodeCastExpression(
                            reqTypeName,
                            new CodeMethodInvokeExpression(
                                new CodeVariableReferenceExpression("reqDcs"),
                                "ReadObject",
                                new CodeExpression[] { new CodeFieldReferenceExpression(
                                                           new CodeVariableReferenceExpression("request"), "Reader") }
                                )
                            )
                        )
                    );
            }

            // Set the request param. If the request is void don't pass anything.
            CodeExpression[] reqParams = reqTypeName == "void" ? new CodeExpression[] { } : new CodeExpression[] { new CodeVariableReferenceExpression("req") };

            // If this is a oneway message or void response return null after processing the request
            if (serviceOp.Operation.Messages.Flow == OperationFlow.OneWay || respTypeName == "void")
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Call service operation to process request."));

                // Add OneWay call to device developer supplied service method implementation
                // Generated Code: m_service.MethodName(req);
                codeMethod.Statements.Add(
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("m_service"),
                        serviceOp.Operation.Name,
                        reqParams
                        )
                    );

                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Return null response for oneway messages"));
                // Generated Code: return null;
                codeMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
                return(codeMethod);
            }

            // If a response object is required create it and call the processing method
            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Create response object"));
            codeMethod.Statements.Add(new CodeCommentStatement("Call service operation to process request and return response."));
            // OutMessagePartName resp;
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    respTypeName,
                    "resp"
                    )
                );
            // Generated Code: resp = m_service.MethodName(req);
            codeMethod.Statements.Add(
                new CodeAssignStatement(
                    new CodeVariableReferenceExpression("resp"),
                    new CodeMethodInvokeExpression(
                        new CodeVariableReferenceExpression("m_service"),
                        serviceOp.Operation.Name,
                        reqParams
                        )
                    )
                );

            codeMethod.Statements.Add(new CodeSnippetStatement(""));
            codeMethod.Statements.Add(new CodeCommentStatement("Create response header"));
            // Generated Code: WsWsaHeader respHeader = new WsWsaHeader(
            //          "http://Some/Namespace/OperationNameResponse",
            //          request.Header.MessageID,
            //          WsWellKnownUri.WsaAnonymousUri,
            //          null, null, null);
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "WsWsaHeader",
                    "respHeader",
                    new CodeObjectCreateExpression(
                        "WsWsaHeader",
                        new CodeExpression[] {
                new CodePrimitiveExpression(serviceOp.OutAction),
                new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(
                                                     new CodeVariableReferenceExpression("request"), "Header"), "MessageID"),
                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("m_version"), "AnonymousUri"),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null),
                new CodePrimitiveExpression(null)
            }
                        )
                    )
                );

            // Generated Code: WsMessage response = new WsMessage(
            //           respHeader,
            //           resp,
            //           WsPrefix.Wsdp);
            codeMethod.Statements.Add(
                new CodeVariableDeclarationStatement(
                    "WsMessage",
                    "response",
                    new CodeObjectCreateExpression(
                        "WsMessage",
                        new CodeExpression[] {
                new CodeVariableReferenceExpression("respHeader"),
                new CodeVariableReferenceExpression("resp"),
                new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("WsPrefix"), "Wsdp")
            }
                        )
                    )
                );

            if (respTypeName != "void")
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Create response serializer"));
                //Generated Code: TypeNameDataContractSerializer respDcs;
                codeMethod.Statements.Add(
                    new CodeVariableDeclarationStatement(
                        CodeGenUtils.GenerateDcsName(respTypeName),
                        "respDcs"
                        )
                    );
                // Generated Code: respDcs = new TypeNameDataContractSerializer("OutMessagePartName", OuputObjectsTypeNamespace);
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeVariableReferenceExpression("respDcs"),
                        new CodeObjectCreateExpression(
                            CodeGenUtils.GenerateDcsName(respTypeName),
                            new CodeExpression[] {
                    new CodePrimitiveExpression(respElementName),
                    new CodePrimitiveExpression(respElementNamespace)
                }
                            )
                        )
                    );
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(new CodeVariableReferenceExpression("response"), "Serializer"),
                        new CodeVariableReferenceExpression("respDcs")
                        )
                    );
            }

            // If this is an mtom message return null after setting body parts
            // If the message encoding is Mtom set the mtom encoded flag and return null else return soap message
            if (encodingType == MessageEncodingType.Mtom)
            {
                codeMethod.Statements.Add(new CodeSnippetStatement(""));
                codeMethod.Statements.Add(new CodeCommentStatement("Indicate that message is Mtom encoded"));

                // response.BodyParts = new WsMtomBodyParts();
                codeMethod.Statements.Add(
                    new CodeAssignStatement(
                        new CodeFieldReferenceExpression(
                            new CodeVariableReferenceExpression("response"), "BodyParts"),
                        new CodeObjectCreateExpression(
                            "WsMtomBodyParts"
                            )
                        )
                    );

                /*
                 * codeMethod.Statements.Add(new CodeSnippetStatement(""));
                 * codeMethod.Statements.Add(new CodeCommentStatement("Build response message and store as first Mtom Bodypart"));
                 * // MessageType = WsMessageType.Mtom;
                 * codeMethod.Statements.Add(
                 *  new CodeAssignStatement(
                 *      new CodeVariableReferenceExpression("MessageType"),
                 *      new CodeFieldReferenceExpression(
                 *          new CodeVariableReferenceExpression("WsMessageType"),
                 *          "Mtom"
                 *      )
                 *  )
                 * );
                 * // BodyParts.Clear();
                 * codeMethod.Statements.Add(
                 *  new CodeMethodInvokeExpression(
                 *      new CodeVariableReferenceExpression("BodyParts"),
                 *      "Clear",
                 *      new CodeExpression[] { }
                 *  )
                 * );
                 * // BodyParts.Start = "<soap@soap>";
                 * codeMethod.Statements.Add(
                 *  new CodeAssignStatement(
                 *      new CodeFieldReferenceExpression(
                 *          new CodeVariableReferenceExpression("BodyParts"),
                 *          "Start"
                 *      ),
                 *      new CodePrimitiveExpression("<soap@soap>")
                 *  )
                 * );
                 * // BodyParts.Add(respDcs.CreateNewBodyPart(SoapMessageBuilder.BuildSoapMessage(respHeader, respDcs, resp), "soap@soap"));
                 * CodeExpression respParams = respTypeName == "void" ? new CodeExpression() : new CodeVariableReferenceExpression("resp");
                 * codeMethod.Statements.Add(
                 *  new CodeMethodInvokeExpression(
                 *      new CodeVariableReferenceExpression("BodyParts"),
                 *      "Add",
                 *      new CodeExpression[] {
                 *          new CodeMethodInvokeExpression(
                 *              new CodeVariableReferenceExpression("respDcs"),
                 *              "CreateNewBodyPart",
                 *              new CodeExpression[] {
                 *                      new CodeMethodInvokeExpression(
                 *                          new CodeVariableReferenceExpression("SoapMessageBuilder"),
                 *                          "BuildSoapMessage",
                 *                          new CodeExpression[] {
                 *                              new CodeVariableReferenceExpression("respHeader"),
                 *                              new CodeVariableReferenceExpression("respDcs"),
                 *                              respParams
                 *                          }
                 *                      ),
                 *                  new CodePrimitiveExpression("<soap@soap>")
                 *              }
                 *          )
                 *      }
                 *  )
                 * );
                 * // BodyParts.Add(respDcs.BodyParts[0]);
                 * codeMethod.Statements.Add(
                 *  new CodeMethodInvokeExpression(
                 *      new CodeVariableReferenceExpression("BodyParts"),
                 *      "Add",
                 *      new CodeExpression[] {
                 *          new CodeIndexerExpression(
                 *              new CodeFieldReferenceExpression(
                 *                  new CodeVariableReferenceExpression("respDcs"),
                 *                  "BodyParts"
                 *              ),
                 *              new CodeExpression[] {
                 *                  new CodePrimitiveExpression(0)
                 *              }
                 *          )
                 *      }
                 *  )
                 * );
                 * // Generated Code: return null;
                 * codeMethod.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(null)));
                 */
            }

            /*
             * else
             * {
             *  codeMethod.Statements.Add(new CodeSnippetStatement(""));
             *  codeMethod.Statements.Add(new CodeCommentStatement("Build response message and return"));
             *  CodeExpression respDcsParam;
             *  CodeExpression respParam;
             *  if (respTypeName == "void")
             *  {
             *      respDcsParam = new CodePrimitiveExpression(null);
             *      respParam = new CodePrimitiveExpression(null);
             *  }
             *  else
             *  {
             *      respDcsParam = new CodeVariableReferenceExpression("respDcs");
             *      respParam = new CodeVariableReferenceExpression("resp");
             *  }
             *
             *  // Generated Code: return SoapMessageBuilder.BuildSoapMessage(respHeader, respDcs, resp);
             *  codeMethod.Statements.Add(
             *      new CodeMethodReturnStatement(
             *          new CodeMethodInvokeExpression(
             *              new CodeVariableReferenceExpression("SoapMessageBuilder"),
             *              "BuildSoapMessage",
             *              new CodeExpression[] {
             *              new CodeVariableReferenceExpression("respHeader"),
             *              respDcsParam,
             *              respParam
             *          }
             *          )
             *      )
             *  );
             * }
             */
            // Generated Code: return SoapMessageBuilder.BuildSoapMessage(respHeader, respDcs, resp);
            codeMethod.Statements.Add(
                new CodeMethodReturnStatement(
                    new CodeVariableReferenceExpression("response")
                    )
                );

            return(codeMethod);
        }