public object Invoke(
     Object clientObj,
     MethodInfo mi,
     params object[] parameters)
 {
     #if (!COMPACT_FRAMEWORK)
       _responseHeaders = null;
       _responseCookies = null;
     #endif
       WebRequest webReq = null;
       object reto = null;
       try
       {
     string useUrl = GetEffectiveUrl(clientObj);
     webReq = GetWebRequest(new Uri(useUrl));
     XmlRpcRequest req = MakeXmlRpcRequest(webReq, mi, parameters,
       clientObj, _xmlRpcMethod, _id);
     SetProperties(webReq);
     SetRequestHeaders(_headers, webReq);
     #if (!COMPACT_FRAMEWORK)
     SetClientCertificates(_clientCertificates, webReq);
     #endif
     Stream serStream = null;
     Stream reqStream = null;
     bool logging = (RequestEvent != null);
     if (!logging)
       serStream = reqStream = webReq.GetRequestStream();
     else
       serStream = new MemoryStream(2000);
     try
     {
       XmlRpcSerializer serializer = new XmlRpcSerializer();
       if (_xmlEncoding != null)
     serializer.XmlEncoding = _xmlEncoding;
       serializer.UseIndentation = _useIndentation;
       serializer.Indentation = _indentation;
       serializer.NonStandard = _nonStandard;
       serializer.UseStringTag = _useStringTag;
       serializer.UseIntTag = _useIntTag;
       serializer.UseEmptyParamsTag = _useEmptyParamsTag;
       serializer.SerializeRequest(serStream, req);
       if (logging)
       {
     reqStream = webReq.GetRequestStream();
     serStream.Position = 0;
     Util.CopyStream(serStream, reqStream);
     reqStream.Flush();
     serStream.Position = 0;
     OnRequest(new XmlRpcRequestEventArgs(req.proxyId, req.number,
       serStream));
       }
     }
     finally
     {
       if (reqStream != null)
     reqStream.Close();
     }
     HttpWebResponse webResp = GetWebResponse(webReq) as HttpWebResponse;
     #if (!COMPACT_FRAMEWORK)
     _responseCookies = webResp.Cookies;
     _responseHeaders = webResp.Headers;
     #endif
     Stream respStm = null;
     Stream deserStream;
     logging = (ResponseEvent != null);
     try
     {
       respStm = webResp.GetResponseStream();
       if (!logging)
       {
     deserStream = respStm;
       }
       else
       {
     deserStream = new MemoryStream(2000);
     Util.CopyStream(respStm, deserStream);
     deserStream.Flush();
     deserStream.Position = 0;
       }
     #if (!COMPACT_FRAMEWORK && !FX1_0)
       deserStream = MaybeDecompressStream((HttpWebResponse)webResp,
     deserStream);
     #endif
       try
       {
     XmlRpcResponse resp = ReadResponse(req, webResp, deserStream, null);
     reto = resp.retVal;
       }
       finally
       {
     if (logging)
     {
       deserStream.Position = 0;
       OnResponse(new XmlRpcResponseEventArgs(req.proxyId, req.number,
         deserStream));
     }
       }
     }
     finally
     {
       if (respStm != null)
     respStm.Close();
     }
       }
       finally
       {
     if (webReq != null)
       webReq = null;
       }
       return reto;
 }
 static void GetRequestStreamCallback(IAsyncResult asyncResult)
 {
     XmlRpcAsyncResult clientResult
     = (XmlRpcAsyncResult)asyncResult.AsyncState;
       clientResult.CompletedSynchronously = asyncResult.CompletedSynchronously;
       try
       {
     Stream serStream = null;
     Stream reqStream = null;
     bool logging = (clientResult.ClientProtocol.RequestEvent != null);
     if (!logging)
     {
       serStream = reqStream
     = clientResult.Request.EndGetRequestStream(asyncResult);
     }
     else
       serStream = new MemoryStream(2000);
     try
     {
       XmlRpcRequest req = clientResult.XmlRpcRequest;
       XmlRpcSerializer serializer = new XmlRpcSerializer();
       if (clientResult.XmlEncoding != null)
     serializer.XmlEncoding = clientResult.XmlEncoding;
       serializer.UseEmptyParamsTag = clientResult.UseEmptyParamsTag;
       serializer.UseIndentation = clientResult.UseIndentation;
       serializer.Indentation = clientResult.Indentation;
       serializer.UseIntTag = clientResult.UseIntTag;
       serializer.UseStringTag = clientResult.UseStringTag;
       serializer.SerializeRequest(serStream, req);
       if (logging)
       {
     reqStream = clientResult.Request.EndGetRequestStream(asyncResult);
     serStream.Position = 0;
     Util.CopyStream(serStream, reqStream);
     reqStream.Flush();
     serStream.Position = 0;
     clientResult.ClientProtocol.OnRequest(
       new XmlRpcRequestEventArgs(req.proxyId, req.number, serStream));
       }
     }
     finally
     {
       if (reqStream != null)
     reqStream.Close();
     }
     clientResult.Request.BeginGetResponse(
       new AsyncCallback(GetResponseCallback), clientResult);
       }
       catch (Exception ex)
       {
     ProcessAsyncException(clientResult, ex);
       }
 }
        //  private methods
        //
        void SerializeMessage(
            IMethodCallMessage mcm,
            ref ITransportHeaders headers,
            ref Stream stream)
        {
            ITransportHeaders reqHeaders = new TransportHeaders();
              reqHeaders["__Uri"] = mcm.Uri;
              reqHeaders["Content-Type"] = "text/xml; charset=\"utf-8\"";
              reqHeaders["__RequestVerb"] = "POST";

              MethodInfo mi = (MethodInfo) mcm.MethodBase;
              string methodName = GetRpcMethodName(mi);
              XmlRpcRequest xmlRpcReq = new XmlRpcRequest(methodName, mcm.InArgs);
              // TODO: possibly call GetRequestStream from next sink in chain?
              // TODO: SoapClientFormatter sink uses ChunkedStream - check why?
              Stream stm = new MemoryStream();
              XmlRpcSerializer serializer = new XmlRpcSerializer();
              serializer.SerializeRequest(stm, xmlRpcReq);
              stm.Position = 0;

              headers = reqHeaders;
              stream = stm;
        }