public static Task <ResolveResponse> ResolveTaskAsync(this DiscoveryClient discoveryClient, ResolveCriteria criteria)
    {
        if (discoveryClient == null)
        {
            throw new ArgumentNullException("discoveryClient");
        }
        TaskCompletionSource <ResolveResponse>   tcs = new TaskCompletionSource <ResolveResponse>(discoveryClient);
        EventHandler <ResolveCompletedEventArgs> completedHandler = null;

        completedHandler = delegate(object sender, ResolveCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <ResolveResponse>(tcs, true, e, () => e.Result, delegate
            {
                discoveryClient.ResolveCompleted -= completedHandler;
            });
        };
        discoveryClient.ResolveCompleted += completedHandler;
        try
        {
            discoveryClient.ResolveAsync(criteria, tcs);
        }
        catch
        {
            discoveryClient.ResolveCompleted -= completedHandler;
            throw;
        }
        return(tcs.Task);
    }
    private static Task SendTaskAsyncCore(SmtpClient smtpClient, object userToken, Action <TaskCompletionSource <object> > sendAsync)
    {
        if (smtpClient == null)
        {
            throw new ArgumentNullException("smtpClient");
        }
        TaskCompletionSource <object> tcs     = new TaskCompletionSource <object>(userToken);
        SendCompletedEventHandler     handler = null;

        handler = delegate(object sender, AsyncCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <object>(tcs, true, e, () => null, delegate
            {
                smtpClient.SendCompleted -= handler;
            });
        };
        smtpClient.SendCompleted += handler;
        try
        {
            sendAsync(tcs);
        }
        catch
        {
            smtpClient.SendCompleted -= handler;
            throw;
        }
        return(tcs.Task);
    }
    private static Task <PingReply> SendTaskAsyncCore(Ping ping, object userToken, Action <TaskCompletionSource <PingReply> > sendAsync)
    {
        if (ping == null)
        {
            throw new ArgumentNullException("ping");
        }
        TaskCompletionSource <PingReply> tcs     = new TaskCompletionSource <PingReply>(userToken);
        PingCompletedEventHandler        handler = null;

        handler = delegate(object sender, PingCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <PingReply>(tcs, true, e, () => e.Reply, delegate
            {
                ping.PingCompleted -= handler;
            });
        };
        ping.PingCompleted += handler;
        try
        {
            sendAsync(tcs);
        }
        catch
        {
            ping.PingCompleted -= handler;
            throw;
        }
        return(tcs.Task);
    }
    public static Task <string> UploadStringTaskAsync(this WebClient webClient, Uri address, string method, string data)
    {
        TaskCompletionSource <string>     tcs     = new TaskCompletionSource <string>(address);
        UploadStringCompletedEventHandler handler = null;

        handler = delegate(object sender, UploadStringCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <string>(tcs, true, e, () => e.Result, delegate
            {
                webClient.UploadStringCompleted -= handler;
            });
        };
        webClient.UploadStringCompleted += handler;
        try
        {
            webClient.UploadStringAsync(address, method, data, tcs);
        }
        catch
        {
            webClient.UploadStringCompleted -= handler;
            throw;
        }
        return(tcs.Task);
    }
    public static Task <Stream> OpenWriteTaskAsync(this WebClient webClient, Uri address, string method)
    {
        TaskCompletionSource <Stream>  tcs     = new TaskCompletionSource <Stream>(address);
        OpenWriteCompletedEventHandler handler = null;

        handler = delegate(object sender, OpenWriteCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <Stream>(tcs, true, e, () => e.Result, delegate
            {
                webClient.OpenWriteCompleted -= handler;
            });
        };
        webClient.OpenWriteCompleted += handler;
        try
        {
            webClient.OpenWriteAsync(address, method, tcs);
        }
        catch
        {
            webClient.OpenWriteCompleted -= handler;
            throw;
        }
        return(tcs.Task);
    }
    public static Task DownloadFileTaskAsync(this WebClient webClient, Uri address, string fileName)
    {
        TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(address);
        AsyncCompletedEventHandler    completedHandler = null;

        completedHandler = delegate(object sender, AsyncCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <object>(tcs, true, e, () => null, delegate
            {
                webClient.DownloadFileCompleted -= completedHandler;
            });
        };
        webClient.DownloadFileCompleted += completedHandler;
        try
        {
            webClient.DownloadFileAsync(address, fileName, tcs);
        }
        catch
        {
            webClient.DownloadFileCompleted -= completedHandler;
            throw;
        }
        return(tcs.Task);
    }
    public static Task <byte[]> DownloadDataTaskAsync(this WebClient webClient, Uri address)
    {
        TaskCompletionSource <byte[]>     tcs = new TaskCompletionSource <byte[]>(address);
        DownloadDataCompletedEventHandler completedHandler = null;

        completedHandler = delegate(object sender, DownloadDataCompletedEventArgs e)
        {
            AsyncCompatLibExtensions.HandleEapCompletion <byte[]>(tcs, true, e, () => e.Result, delegate
            {
                webClient.DownloadDataCompleted -= completedHandler;
            });
        };
        webClient.DownloadDataCompleted += completedHandler;
        try
        {
            webClient.DownloadDataAsync(address, tcs);
        }
        catch
        {
            webClient.DownloadDataCompleted -= completedHandler;
            throw;
        }
        return(tcs.Task);
    }