/// <summary>
        /// Match the waiting connection with a registration, callback registration,
        /// return if connection is accepted in event.
        /// </summary>
        /// <returns>true if a match was found.</returns>
        private bool MatchRegistration(object sender, ConnectionWaitingEventArgs e)
        {
            Registration callbackRegistration = null;
            bool         found = false;

            lock (m_registrationsLock)
            {
                // first try to match single registrations
                foreach (var registration in m_registrations.Where(r => (r.ReverseConnectStrategy & ReverseConnectStrategy.Any) == 0))
                {
                    if (registration.EndpointUrl.Scheme.Equals(e.EndpointUrl.Scheme, StringComparison.InvariantCulture) &&
                        (registration.ServerUri == e.ServerUri ||
                         registration.EndpointUrl.Authority.Equals(e.EndpointUrl.Authority, StringComparison.InvariantCulture)))
                    {
                        callbackRegistration = registration;
                        e.Accepted           = true;
                        found = true;
                        Utils.Trace("Accepted reverse connection: {0} {1}", e.ServerUri, e.EndpointUrl);
                        break;
                    }
                }

                // now try any registrations.
                if (callbackRegistration == null)
                {
                    foreach (var registration in m_registrations.Where(r => (r.ReverseConnectStrategy & ReverseConnectStrategy.Any) != 0))
                    {
                        if (registration.EndpointUrl.Scheme.Equals(e.EndpointUrl.Scheme, StringComparison.InvariantCulture))
                        {
                            callbackRegistration = registration;
                            e.Accepted           = true;
                            found = true;
                            Utils.Trace("Accept any reverse connection for approval: {0} {1}", e.ServerUri, e.EndpointUrl);
                            break;
                        }
                    }
                }

                if (callbackRegistration != null)
                {
                    if ((callbackRegistration.ReverseConnectStrategy & ReverseConnectStrategy.Once) != 0)
                    {
                        m_registrations.Remove(callbackRegistration);
                    }
                }
            }

            callbackRegistration?.OnConnectionWaiting?.Invoke(sender, e);

            return(found);
        }
        /// <summary>
        /// Raised when a reverse connection is waiting,
        /// finds and calls a waiting connection.
        /// </summary>
        private async Task OnConnectionWaiting(object sender, ConnectionWaitingEventArgs e)
        {
            DateTime startTime = DateTime.UtcNow;
            DateTime endTime   = startTime + TimeSpan.FromMilliseconds(m_configuration.HoldTime);
            bool     matched   = MatchRegistration(sender, e);

            while (!matched)
            {
                Utils.Trace("Holding reverse connection: {0} {1}", e.ServerUri, e.EndpointUrl);
                CancellationToken ct;
                lock (m_registrationsLock)
                {
                    ct = m_cts.Token;
                }
                TimeSpan delay = endTime - DateTime.UtcNow;
                if (delay.TotalMilliseconds > 0)
                {
                    await Task.Delay(delay, ct).ContinueWith(tsk => {
                        if (tsk.IsCanceled)
                        {
                            matched = MatchRegistration(sender, e);
                            if (matched)
                            {
                                Utils.Trace("Matched reverse connection {0} {1} after {2}ms",
                                            e.ServerUri, e.EndpointUrl,
                                            (int)(DateTime.UtcNow - startTime).TotalMilliseconds);
                            }
                        }
                    }
                                                             ).ConfigureAwait(false);
                }
                break;
            }

            Utils.Trace("{0} reverse connection: {1} {2} after {3}ms",
                        e.Accepted ? "Accepted" : "Rejected",
                        e.ServerUri, e.EndpointUrl, (int)(DateTime.UtcNow - startTime).TotalMilliseconds);
        }