public Task <Match> WaitForMatch(Regex regex)
        {
            TaskCompletionSource <Match> tcs = new TaskCompletionSource <Match>();
            object completionLock            = new object();

            EventedStreamReader.OnReceivedLineHandler onReceivedLineHandler = (EventedStreamReader.OnReceivedLineHandler)null;
            EventedStreamReader.OnStreamClosedHandler onStreamClosedHandler = (EventedStreamReader.OnStreamClosedHandler)null;
            onReceivedLineHandler = (EventedStreamReader.OnReceivedLineHandler)(line =>
            {
                Match match = regex.Match(line);
                if (!match.Success)
                {
                    return;
                }
                ResolveIfStillPending((Action)(() => tcs.SetResult(match)));
            });
            onStreamClosedHandler = (EventedStreamReader.OnStreamClosedHandler)(() => ResolveIfStillPending((Action)(() => tcs.SetException((Exception) new EndOfStreamException()))));
            this.OnReceivedLine  += onReceivedLineHandler;
            this.OnStreamClosed  += onStreamClosedHandler;
            return(tcs.Task);

            void ResolveIfStillPending(Action applyResolution)
            {
                lock (completionLock)
                {
                    if (tcs.Task.IsCompleted)
                    {
                        return;
                    }
                    this.OnReceivedLine -= onReceivedLineHandler;
                    this.OnStreamClosed -= onStreamClosedHandler;
                    applyResolution();
                }
            }
        }
 private void OnClosed()
 {
     EventedStreamReader.OnStreamClosedHandler onStreamClosed = this.OnStreamClosed;
     if (onStreamClosed == null)
     {
         return;
     }
     onStreamClosed();
 }