public object Execute(ExecContext ctx)
        {
            if (ctx == null)
            {
                throw new ArgumentNullException("ctx", "Execution context cannot be null");
            }

            object objInvokeResult = null;
            string strRetVal       = "";
            string strError        = "";

            // Load Assembly containing web service proxy
            bool     bProxyMethodHasParameters = false;
            Assembly a = Assembly.LoadFrom(ctx.Assembly);
            // Get the correct type (ProxyClass)
            Type ProxyType = a.GetType(ctx.ServiceName);
            // Create an instance of the Proxy Class
            Object objProxy = a.CreateInstance(ctx.ServiceName);

            if (objProxy == null || ProxyType == null)
            {
                strError  = "Cannot create type/proxy instance ";
                strError += ctx.ServiceName;
                strError += " in assembly ";
                strError += ctx.Assembly;
                throw new Exception(strError);
            }

            // Check whether Proxy class has a property
            // called Url, valid for generated
            // proxies, if it does check its value
            // if value is empty fill in proxy access point
            PropertyInfo Url = ProxyType.GetProperty("Url");

            if (Url != null)
            {
                string strUrl = (string)Url.GetValue(objProxy, null);
                if (strUrl.Length == 0)
                {
                    Url.SetValue(objProxy, ctx.AccessPointUrl, null);
                }
            }

            // Once we have a Proxy Object and a Type instance
            // use reflection to get info on method to be
            // executed.
            MethodInfo mInfo = ProxyType.GetMethod(ctx.MethodName);

            if (mInfo == null)
            {
                strError  = "Cannot find method ";
                strError += ctx.MethodName;
                strError += " of Proxy ";
                strError += ctx.ServiceName;
                strError += " loaded from assembly ";
                strError += ctx.Assembly;
                throw new System.Exception(strError);
            }

            // Get info on parameters expected by Proxy method
            ParameterInfo[] arrParamInfo = mInfo.GetParameters();
            if (arrParamInfo.Length > 0)
            {
                bProxyMethodHasParameters = true;
            }

            Object[] param = null;

            if (bProxyMethodHasParameters)
            {
                // Number parameters passed not equal to number parameters expected
                if (ctx.Parameters.Count != arrParamInfo.Length)
                {
                    throw new Exception("Wrong Number of Arguments Passed to Proxy ");
                }

                // Create array to hold parameters
                param = new Object[arrParamInfo.Length];

                // Try deserialization
                for (int i = 0; i < ctx.Parameters.Count; i++)
                {
                    // Get the expected type
                    Type paramType = arrParamInfo[i].ParameterType;
                    // Create XmlSerializer
                    XmlSerializer xs = new XmlSerializer(paramType);
                    // Read in Xml doc representing parameter
                    System.Xml.XmlReader xt = new XmlTextReader((string)ctx.Parameters[i], XmlNodeType.Document, null);
                    xt.Read();
                    // Deserialize
                    Object paramInst = xs.Deserialize(xt);
                    // Store in parameter array
                    param[i] = (Object)paramInst;
                }
            }            // End if bProxyMethodHasParameters

            // Add digital signatures and/or encryption based on
            // the Executor settings
            if (m_settings.SignSoapMessage || m_settings.EncryptSoapMessage)
            {
                // Sign message
                X509SecurityToken signatureToken = new X509SecurityToken(this.Settings.SigningCertificate);
                // Ask proxy for RequestContext property
                PropertyInfo requestSoapContextProp = ProxyType.GetProperty("RequestSoapContext");
                SoapContext  reqSoapCtx             = null;

                // If property exists
                if (requestSoapContextProp != null)
                {
                    // Get property value
                    reqSoapCtx = (SoapContext)requestSoapContextProp.GetValue(objProxy, null);
                    // Make changes to property value
                    // Add security token to SOAP message header
                    reqSoapCtx.Security.Tokens.Add(signatureToken);
                    // Create a signature element from the token
                    Signature sig = new Signature(signatureToken);
                    // Sign the mesage body
                    sig.SignatureOptions = SignatureOptions.IncludeSoapBody;
                    // Add digital signature
                    reqSoapCtx.Security.Elements.Add(sig);

                    // Encrypt SOAP message
                    if (m_settings.EncryptSoapMessage)
                    {
                        X509SecurityToken encryptionToken = new X509SecurityToken(this.m_settings.EncryptionCertificate);
                        // Add encryption token to SOAP message header
                        reqSoapCtx.Security.Tokens.Add(encryptionToken);
                        // Encrypt message
                        EncryptedData enc = new EncryptedData(encryptionToken);
                        reqSoapCtx.Security.Elements.Add(enc);
                    }    // End-if encrypting SOAP message
                }        // End-if RequestSoapContext property exposed by proxy
            }            //End-if SOAP message is to be digitally signed or encrypted

            if (bProxyMethodHasParameters)
            {
                objInvokeResult = ProxyType.InvokeMember(ctx.MethodName,
                                                         BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
                                                         null,
                                                         objProxy,
                                                         param);
            }

            else
            {
                objInvokeResult = ProxyType.InvokeMember(ctx.MethodName,
                                                         BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.Static,
                                                         null,
                                                         objProxy,
                                                         null);
            }

            // Check for digitally signed response
            if (this.m_settings.ExpectSignedResponse)
            {
                this.m_settings.ResponseCertificate = null;

                // Get the response certificate
                // Ask proxy for ResponseContext property
                PropertyInfo responseSoapContextProp = ProxyType.GetProperty("ResponseSoapContext");
                SoapContext  respSoapCtx             = null;

                // If property exists
                if (responseSoapContextProp != null)
                {
                    // Get property value
                    respSoapCtx = (SoapContext)responseSoapContextProp.GetValue(objProxy, null);
                    // Inspect the response SOAP context
                    if (respSoapCtx.Security.Elements.Count != 1)
                    {
                        throw new Exception("Expected a single security element");
                    }

                    object objElement = respSoapCtx.Security.Elements[0];
                    if (!(objElement is Microsoft.Web.Services.Security.Signature))
                    {
                        throw new Exception("Expected a digital signature element");
                    }

                    Microsoft.Web.Services.Security.Signature signature = objElement as Microsoft.Web.Services.Security.Signature;
                    if (signature.SignatureOptions != SignatureOptions.IncludeSoapBody)
                    {
                        throw new Exception("Expected the body of the SOAP message to be signed");
                    }

                    // If the signature verifies set the response cert
                    if (!signature.CheckSignature())
                    {
                        throw new Exception("Error verifying digital signature");
                    }

                    X509SecurityToken tok = (X509SecurityToken)signature.SecurityToken;
                    this.m_settings.ResponseCertificate = tok.Certificate;
                }
            }

            if (objInvokeResult != null)
            {
                // Otherwise serialize results to XML
                // Get returned type
                Type returnType = objInvokeResult.GetType();
                // Create XmlSerializer
                XmlSerializer ser = new XmlSerializer(returnType);
                // Create a memory stream
                MemoryStream ms = new MemoryStream();
                // Serialize to stream ms
                ser.Serialize(ms, objInvokeResult);
                // Goto start of stream
                ms.Seek(0, System.IO.SeekOrigin.Begin);
                // Create a stream reader
                TextReader reader = new StreamReader(ms);
                // Read entire stream, this is our return value
                strRetVal = reader.ReadToEnd();
                // Close reader
                reader.Close();
                // Close stream
                ms.Close();
            }

            return(strRetVal);
        }
        public object Execute(object objCtx)
        {
            ExecContext ctx = objCtx as ExecContext;

            return(this.Execute(ctx));
        }