/// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="sipStack">Reference to SIP stack.</param>
        /// <param name="request">SIP request to what caused to create client transaction.</param>
        /// <param name="destination">Remote destination info.</param>
        /// <param name="addVia">Specified if transaction adds new Via: header. If this value is false,
        /// then its user responsibility to add valid Via: header to <b>request</b> argument.</param>
        internal SIP_ClientTransaction(SIP_Stack sipStack,SIP_Request request,SIP_Destination destination,bool addVia)
        {
            m_pSipStack    = sipStack;
            m_pRequest     = request;
            m_pDestination = destination;

            m_pResponses = new List<SIP_Response>();

            // Add Via: header field.
            if(addVia){
                m_ID = SIP_t_ViaParm.CreateBranch();
                SIP_t_ViaParm via = new SIP_t_ViaParm();
                via.ProtocolName = "SIP";
                via.ProtocolVersion = "2.0";
                via.ProtocolTransport = m_pDestination.Transport;
                via.SentBy = "transport_layer_will_replace_it";
                via.Branch = m_ID;
                request.Via.AddToTop(via.ToStringValue());
            }
            // User provided Via:.
            else{
                // Validate Via:
                SIP_t_ViaParm via = request.Via.GetTopMostValue();
                if(via == null){
                    throw new ArgumentException("Via: header is missing !");
                }
                if(via.Branch == null){
                    throw new ArgumentException("Via: header 'branch' prameter is missing !");
                }

                m_ID = via.Branch;
            }
        }
        /// <summary>
        /// Creates new SIP client transaction for specified request.
        /// </summary>
        /// <param name="request">SIP request.</param>
        /// <param name="destination">Remote destination info.</param>
        /// <param name="addVia">Specified if transaction adds new Via: header. If this value is false,
        /// then its user responsibility to add vlid Via: header to <b>request</b> argument.</param>
        /// <returns>Returns ncreated SIP client transaction.</returns>
        public SIP_ClientTransaction CreateClientTransaction(SIP_Request request,SIP_Destination destination,bool addVia)
        {
            SIP_ClientTransaction transaction = new SIP_ClientTransaction(m_pSipStack,request,destination,addVia);
            m_pClientTransactions.Add(transaction);

            return transaction;
        }
        /// <summary>
        /// Default constructor.
        /// </summary>
        /// <param name="stack">Owner stack.</param>
        /// <param name="request">Request to forward.</param>
        /// <param name="forkingMode">Specifies how proxy context must handle forking.</param>
        /// <param name="noCancel">Specifies if proxy should not send Cancel to forked requests.</param>
        /// <param name="noRecurse">Specifies what proxy server does when it gets 3xx response. If true proxy will forward
        /// request to new specified address if false, proxy will return 3xx response to caller.</param>
        /// <param name="destinations">Possible destinations. NOTE: These values must be in priority order !</param>
        /// <exception cref="ArgumentNullException">Is raised when any of the reference type prameters is null.</exception>
        public SIP_ProxyContext(SIP_Stack stack,SIP_Request request,SIP_ForkingMode forkingMode,bool noCancel,bool noRecurse,SIP_Destination[] destinations)
        {
            if(stack == null){
                throw new ArgumentNullException("stack");
            }
            if(request == null){
                throw new ArgumentNullException("serverTransaction");
            }
            if(destinations == null){
                throw new ArgumentNullException("destinations");
            }

            m_pStack = stack;

            m_pServerTransaction = stack.TransactionLayer.CreateServerTransaction(request);
            m_pServerTransaction.CanCreateDialog = false;
            m_pServerTransaction.Canceled += new EventHandler(m_pServerTransaction_Canceled);
            m_pServerTransaction.Terminated += new EventHandler(m_pServerTransaction_Terminated);

            m_ForkingMode = forkingMode;
            m_NoCancel    = noCancel;
            m_NoRecurse   = noRecurse;

            m_pClientTransactions = new List<SIP_ClientTransaction>();
            m_pResponses          = new List<SIP_Response>();
            m_CreateTime          = DateTime.Now;

            // Queue destinations up, higest to lowest.
            m_pRemainingDestinations = new Queue<SIP_Destination>();
            foreach(SIP_Destination destination in destinations){
                m_pRemainingDestinations.Enqueue(destination);
            }
        }
        /// <summary>
        /// Creates client transaction and starts processing it.
        /// </summary>
        /// <param name="destination">SIP destination.</param>
        private void CreateClientTransaction(SIP_Destination destination)
        {
            /* Sequential handling:
                If there are more that 1 destination, then m_SequentialTimeout interval
                is used to to try next destination.
                Otherwise 3 minute is used.
            */

            SIP_ClientTransaction transaction = m_pStack.TransactionLayer.CreateClientTransaction(m_pServerTransaction.Request.Copy(),destination,true);
            if(m_ForkingMode == SIP_ForkingMode.Sequential && m_pRemainingDestinations.Count > 0){
                transaction.Timeout = 15;
            }
            else{
                transaction.Timeout = 180;
            }
            transaction.CanCreateDialog = false;
            transaction.ResponseReceived += new SIP_ResponseReceivedEventHandler(ClientTransaction_ResponseReceived);
            transaction.TimedOut += new EventHandler(ClientTransaction_TimedOut);
            transaction.TransportError += new EventHandler(ClientTransaction_TransportError);
            transaction.Terminated += new EventHandler(ClientTransaction_Terminated);
            m_pClientTransactions.Add(transaction);
            transaction.Begin();
        }
 /// <summary>
 /// Sends request to the specified destination.
 /// </summary>
 /// <param name="request">SIP request to send.</param>
 /// <param name="destination">Destination info.</param>
 /// <exception cref="SIP_TransportException">Is raised when sending fails.</exception>
 public void SendRequest(SIP_Request request,SIP_Destination destination)
 {
     try{
         SendRequest(request,destination.LocalEndPoint,new IPEndPoint(System.Net.Dns.GetHostAddresses(destination.Host)[0],destination.Port),destination.Transport);
     }
     catch(Exception x){
         throw new SIP_TransportException(x.Message);
     }
 }