private static IEnumerator <int> CopyStream(AsyncEnumerator ae, Stream readStream, Stream writeStream)
        {
            byte[][] buffer = new byte[][]
            {
                new byte[8192],
                new byte[8192]
            };
            int bytesRead     = 0;
            int currentBuffer = 0;

            ae.AddAsync <IAsyncResult>(readStream.BeginRead(buffer[currentBuffer], 0, buffer[0].Length, ae.GetAsyncCallback(), null));
            yield return(1);

            for (bytesRead = readStream.EndRead(ae.CompletedAsyncResults[0]); bytesRead > 0; bytesRead = readStream.EndRead(ae.CompletedAsyncResults[1]))
            {
                ae.AddAsync <IAsyncResult>(writeStream.BeginWrite(buffer[currentBuffer % 2], 0, bytesRead, ae.GetAsyncCallback(), null));
                currentBuffer++;
                ae.AddAsync <IAsyncResult>(readStream.BeginRead(buffer[currentBuffer % 2], 0, buffer[currentBuffer % 2].Length, ae.GetAsyncCallback(), null));
                yield return(2);

                writeStream.EndWrite(ae.CompletedAsyncResults[0]);
            }
            ae.End();
            yield break;
        }
        private IEnumerator <int> ProcessProxyRequest(AsyncEnumerator ae)
        {
            ExTraceGlobals.ProxyCallTracer.TraceDebug((long)this.GetHashCode(), "ProxyEventHandler.SendProxyRequest");
            base.DontWriteHeaders = true;
            int newContentLength = 0;

            byte[]         soapHeaderStuff      = this.GetRequestSoapHeader(out newContentLength);
            HttpWebRequest webRequest           = this.GetProxyRequest(newContentLength);
            WindowsImpersonationContext context = NetworkServiceImpersonator.Impersonate();

            try
            {
                ae.AddAsync <IAsyncResult>(webRequest.BeginGetRequestStream(ae.GetAsyncCallback(), null));
            }
            catch
            {
                context.Undo();
                context = null;
                throw;
            }
            finally
            {
                if (context != null)
                {
                    context.Undo();
                    context = null;
                }
            }
            yield return(1);

            Stream outStream = this.DoWebAction <Stream>(() => webRequest.EndGetRequestStream(ae.CompletedAsyncResults[0]));

            if (outStream == null)
            {
                ae.End();
            }
            else
            {
                using (outStream)
                {
                    ae.AddAsync <IAsyncResult>(outStream.BeginWrite(soapHeaderStuff, 0, soapHeaderStuff.Length, ae.GetAsyncCallback(), null));
                    yield return(1);

                    outStream.EndWrite(ae.CompletedAsyncResults[0]);
                    AsyncResult asyncResult = ae.AddAsyncEnumerator((AsyncEnumerator ae1) => ProxyToEwsEventHandler.CopyStream(ae1, this.HttpContext.Request.InputStream, outStream));
                    yield return(1);

                    asyncResult.End();
                }
                ae.AddAsync <IAsyncResult>(webRequest.BeginGetResponse(ae.GetAsyncCallback(), null));
                yield return(1);

                HttpWebResponse webResponse = this.DoWebAction <HttpWebResponse>(() => (HttpWebResponse)webRequest.EndGetResponse(ae.CompletedAsyncResults[0]));
                if (webResponse != null)
                {
                    using (webResponse)
                    {
                        ae.AddAsyncEnumerator((AsyncEnumerator ae1) => this.ProcessWebResponse(ae1, webResponse));
                        yield return(1);
                    }
                }
                ae.End();
            }
            yield break;
        }