/// <summary>
        /// The event handler for responses to the authenticated register request.
        /// </summary>
        private void AuthResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint,
                                          SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                logger.LogDebug("Server auth response " + sipResponse.Status + " received for " +
                                m_sipAccountAOR.ToString() + ".");

                if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                {
                    if (m_expiry > 0)
                    {
                        m_isRegistered = true;
                        m_expiry       = GetUpdatedExpiry(sipResponse);
                        RegistrationSuccessful?.Invoke(m_sipAccountAOR);
                    }
                    else
                    {
                        m_isRegistered = false;
                        RegistrationRemoved?.Invoke(m_sipAccountAOR);
                    }

                    m_waitForRegistrationMRE.Set();
                }
                else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                {
                    m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                    logger.LogDebug("Registration for " + m_sipAccountAOR.ToString() +
                                    " had a too short expiry, updated to +" + m_expiry + " and trying again.");
                    SendInitialRegister();
                }
                else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden ||
                         sipResponse.Status == SIPResponseStatusCodesEnum.NotFound ||
                         sipResponse.Status == SIPResponseStatusCodesEnum.PaymentRequired)
                {
                    // SIP account does not appear to exist.
                    logger.LogWarning("Registration failed with " + sipResponse.Status + " for " +
                                      m_sipAccountAOR.ToString() + ", no further registration attempts will be made.");
                    string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank())
                        ? sipResponse.Status.ToString()
                        : sipResponse.ReasonPhrase;
                    RegistrationFailed?.Invoke(m_sipAccountAOR,
                                               "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                    m_exit = true;
                    m_waitForRegistrationMRE.Set();
                }
                else if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired ||
                         sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    // SIP account credentials failed.
                    logger.LogWarning("Registration failed with " + sipResponse.Status + " for " +
                                      m_sipAccountAOR.ToString() + ", no further registration attempts will be made.");
                    string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank())
                        ? sipResponse.Status.ToString()
                        : sipResponse.ReasonPhrase;
                    RegistrationFailed?.Invoke(m_sipAccountAOR,
                                               "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                    m_exit = true;
                    m_waitForRegistrationMRE.Set();
                }
                else
                {
                    logger.LogWarning("Registration failed with " + sipResponse.Status + " for " +
                                      m_sipAccountAOR.ToString() + ".");
                    m_isRegistered = false;
                    RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                         "Registration failed with " + sipResponse.Status + ".");
                    m_waitForRegistrationMRE.Set();
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPRegistrationUserAgent AuthResponseReceived. " + excp.Message);
            }
        }
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Server response " + sipResponse.Status + " received for " + m_sipAccountAOR.ToString() + ".", m_owner));

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.AuthenticationHeader != null)
                    {
                        if (m_attempts >= MAX_REGISTER_ATTEMPTS)
                        {
                            Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.", m_owner));
                            m_isRegistered = false;
                            RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts.");
                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;
                            SIPRequest authenticatedRequest            = GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse);
                            SIPNonInviteTransaction regAuthTransaction = m_sipTransport.CreateNonInviteTransaction(authenticatedRequest, sipTransaction.RemoteEndPoint, localSIPEndPoint, m_outboundProxy);
                            regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) => { ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); }); };
                            regAuthTransaction.NonInviteTransactionTimedOut += (tn) => { ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); }); };
                            m_sipTransport.SendSIPReliable(regAuthTransaction);
                        }
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied for " + m_sipAccountAOR.ToString() + ".", m_owner));
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + " but no authentication header was supplied.");
                        m_waitForRegistrationMRE.Set();
                    }
                }
                else
                {
                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        if (m_expiry > 0)
                        {
                            m_isRegistered = true;
                            m_expiry       = GetUpdatedExpiry(sipResponse);
                            RegistrationSuccessful?.Invoke(m_sipAccountAOR);
                        }
                        else
                        {
                            m_isRegistered = false;
                            RegistrationRemoved?.Invoke(m_sipAccountAOR);
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound)
                    {
                        // SIP account does not appear to exist.
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ", no further registration attempts will be made.", m_owner));
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase;
                        RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                        m_exit = true;
                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterInProgress, "Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again.", m_owner));
                        SendInitialRegister();
                    }
                    else
                    {
                        Log_External(new SIPMonitorConsoleEvent(SIPMonitorServerTypesEnum.UserAgentClient, SIPMonitorEventTypesEnum.ContactRegisterFailed, "Registration failed with " + sipResponse.Status + " for " + m_sipAccountAOR.ToString() + ".", m_owner));
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration failed with " + sipResponse.Status + ".");
                        m_waitForRegistrationMRE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.Error("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " + excp.Message);
            }
        }
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint,
                                            SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                logger.LogDebug("Server response " + sipResponse.Status + " received for " +
                                m_sipAccountAOR.ToString() + ".");

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired ||
                    sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.AuthenticationHeader != null)
                    {
                        if (m_attempts >= m_maxRegisterAttempts)
                        {
                            logger.LogDebug("Registration to " + m_sipAccountAOR.ToString() +
                                            " reached the maximum number of allowed attempts without a failure condition.");
                            m_isRegistered = false;
                            RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                                 "Registration reached the maximum number of allowed attempts.");
                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;
                            SIPRequest authenticatedRequest =
                                GetAuthenticatedRegistrationRequest(sipTransaction.TransactionRequest, sipResponse);
                            SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                            if (registrarSIPEndPoint == null)
                            {
                                //SIPDNSLookupResult lookupResult = m_sipTransport.GetHostEndPoint(m_registrarHost, false);
                                SIPURI uri          = SIPURI.ParseSIPURIRelaxed(m_registrarHost);
                                var    lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).ConfigureAwait(false)
                                                      .GetAwaiter().GetResult();
                                if (lookupResult == null)
                                {
                                    logger.LogWarning("Could not resolve " + m_registrarHost + ".");
                                }
                                else
                                {
                                    registrarSIPEndPoint = lookupResult;
                                }
                            }

                            if (registrarSIPEndPoint == null)
                            {
                                logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + ".");

                                RegistrationFailed?.Invoke(m_sipAccountAOR,
                                                           "Could not resolve " + m_registrarHost + ".");
                            }
                            else
                            {
                                SIPNonInviteTransaction regAuthTransaction = new SIPNonInviteTransaction(m_sipTransport,
                                                                                                         authenticatedRequest, registrarSIPEndPoint);
                                regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                                {
                                    ThreadPool.QueueUserWorkItem(delegate { AuthResponseReceived(lep, rep, tn, rsp); });
                                    return(Task.FromResult(SocketError.Success));
                                };
                                regAuthTransaction.NonInviteTransactionTimedOut += (tn) =>
                                {
                                    ThreadPool.QueueUserWorkItem(delegate { RegistrationTimedOut(tn); });
                                };
                                m_sipTransport.SendTransaction(regAuthTransaction);
                            }
                        }
                    }
                    else
                    {
                        logger.LogWarning("Registration failed with " + sipResponse.Status +
                                          " but no authentication header was supplied for " +
                                          m_sipAccountAOR.ToString() + ".");
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                             "Registration failed with " + sipResponse.Status +
                                                             " but no authentication header was supplied.");
                        m_waitForRegistrationMRE.Set();
                    }
                }
                else
                {
                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        if (m_expiry > 0)
                        {
                            m_isRegistered = true;
                            m_expiry       = GetUpdatedExpiry(sipResponse);
                            RegistrationSuccessful?.Invoke(m_sipAccountAOR);
                        }
                        else
                        {
                            m_isRegistered = false;
                            RegistrationRemoved?.Invoke(m_sipAccountAOR);
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden ||
                             sipResponse.Status == SIPResponseStatusCodesEnum.NotFound)
                    {
                        // SIP account does not appear to exist.
                        logger.LogWarning("Registration failed with " + sipResponse.Status + " for " +
                                          m_sipAccountAOR.ToString() +
                                          ", no further registration attempts will be made.");
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank())
                            ? sipResponse.Status.ToString()
                            : sipResponse.ReasonPhrase;
                        RegistrationFailed?.Invoke(m_sipAccountAOR,
                                                   "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");
                        m_exit = true;
                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        logger.LogWarning("Registration for " + m_sipAccountAOR.ToString() +
                                          " had a too short expiry, updated to +" + m_expiry + " and trying again.");
                        SendInitialRegister();
                    }
                    else
                    {
                        logger.LogWarning("Registration failed with " + sipResponse.Status + " for " +
                                          m_sipAccountAOR.ToString() + ".");
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR,
                                                             "Registration failed with " + sipResponse.Status + ".");
                        m_waitForRegistrationMRE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError("Exception SIPRegistrationUserAgent ServerResponseReceived (" + remoteEndPoint + "). " +
                                excp.Message);
            }
        }
        /// <summary>
        /// The event handler for responses to the initial register request.
        /// </summary>
        private void ServerResponseReceived(SIPEndPoint localSIPEndPoint, SIPEndPoint remoteEndPoint, SIPTransaction sipTransaction, SIPResponse sipResponse)
        {
            try
            {
                logger.LogDebug($"Server response {sipResponse.Status} received for {m_sipAccountAOR}.");

                if (sipResponse.Status == SIPResponseStatusCodesEnum.ProxyAuthenticationRequired || sipResponse.Status == SIPResponseStatusCodesEnum.Unauthorised)
                {
                    if (sipResponse.Header.HasAuthenticationHeader)
                    {
                        if (m_attempts >= m_maxRegisterAttempts)
                        {
                            logger.LogDebug("Registration to " + m_sipAccountAOR.ToString() + " reached the maximum number of allowed attempts without a failure condition.");
                            m_isRegistered = false;
                            RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, "Registration reached the maximum number of allowed attempts.");
                            m_waitForRegistrationMRE.Set();
                        }
                        else
                        {
                            m_attempts++;

                            string username             = (m_authUsername != null) ? m_authUsername : m_sipAccountAOR.User;
                            var    authenticatedRequest = sipTransaction.TransactionRequest.DuplicateAndAuthenticate(
                                sipResponse.Header.AuthenticationHeaders, username, m_password);

                            SIPEndPoint registrarSIPEndPoint = m_outboundProxy;
                            if (registrarSIPEndPoint == null)
                            {
                                SIPURI uri          = SIPURI.ParseSIPURIRelaxed(m_registrarHost);
                                var    lookupResult = m_sipTransport.ResolveSIPUriAsync(uri).Result;
                                if (lookupResult == null)
                                {
                                    logger.LogWarning("Could not resolve " + m_registrarHost + ".");
                                }
                                else
                                {
                                    registrarSIPEndPoint = lookupResult;
                                }
                            }
                            if (registrarSIPEndPoint == null)
                            {
                                logger.LogWarning("SIPRegistrationAgent could not resolve " + m_registrarHost + ".");

                                RegistrationFailed?.Invoke(m_sipAccountAOR, "Could not resolve " + m_registrarHost + ".");
                            }
                            else
                            {
                                SIPNonInviteTransaction regAuthTransaction = new SIPNonInviteTransaction(m_sipTransport, authenticatedRequest, registrarSIPEndPoint);
                                regAuthTransaction.NonInviteTransactionFinalResponseReceived += (lep, rep, tn, rsp) =>
                                {
                                    AuthResponseReceived(lep, rep, tn, rsp);
                                    return(Task.FromResult(SocketError.Success));
                                };
                                regAuthTransaction.NonInviteTransactionFailed += RegistrationTransactionFailed;
                                regAuthTransaction.SendRequest();
                            }
                        }
                    }
                    else
                    {
                        logger.LogWarning($"Registration failed with {sipResponse.Status} but no authentication header was supplied for {m_sipAccountAOR}.");
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, $"Registration failed with {sipResponse.Status} but no authentication header was supplied.");
                        m_waitForRegistrationMRE.Set();
                    }
                }
                else
                {
                    if (sipResponse.Status == SIPResponseStatusCodesEnum.Ok)
                    {
                        if (m_expiry > 0)
                        {
                            m_isRegistered = true;
                            m_expiry       = GetUpdatedExpiry(sipResponse);
                            RegistrationSuccessful?.Invoke(m_sipAccountAOR);
                        }
                        else
                        {
                            m_isRegistered = false;
                            RegistrationRemoved?.Invoke(m_sipAccountAOR);
                        }

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.Forbidden || sipResponse.Status == SIPResponseStatusCodesEnum.NotFound)
                    {
                        // SIP account does not appear to exist.
                        m_exit = m_exitOnUnequivocalFailure;

                        logger.LogWarning($"Registration unequivocal failure with {sipResponse.Status} for {m_sipAccountAOR}{(m_exit ? ", no further registration attempts will be made" : "")}.");
                        string reasonPhrase = (sipResponse.ReasonPhrase.IsNullOrBlank()) ? sipResponse.Status.ToString() : sipResponse.ReasonPhrase;
                        RegistrationFailed?.Invoke(m_sipAccountAOR, "Registration failed with " + (int)sipResponse.Status + " " + reasonPhrase + ".");

                        m_waitForRegistrationMRE.Set();
                    }
                    else if (sipResponse.Status == SIPResponseStatusCodesEnum.IntervalTooBrief && m_expiry != 0)
                    {
                        m_expiry = GetUpdatedExpiryForIntervalTooBrief(sipResponse);
                        logger.LogWarning("Registration for " + m_sipAccountAOR.ToString() + " had a too short expiry, updated to +" + m_expiry + " and trying again.");
                        SendInitialRegister();
                    }
                    else
                    {
                        logger.LogWarning($"Registration failed with {sipResponse.Status} for {m_sipAccountAOR}.");
                        m_isRegistered = false;
                        RegistrationTemporaryFailure?.Invoke(m_sipAccountAOR, $"Registration failed with {sipResponse.Status}.");
                        m_waitForRegistrationMRE.Set();
                    }
                }
            }
            catch (Exception excp)
            {
                logger.LogError($"Exception SIPRegistrationUserAgent ServerResponseReceived ({remoteEndPoint}). {excp}");
            }
        }