/// <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>
        /// Default constructor.
        /// </summary>
        /// <param name="proxy">Owner proxy.</param>
        /// <param name="transaction">Server transaction what is used to send SIP responses back to caller.</param>
        /// <param name="request">Request to forward.</param>
        /// <param name="addRecordRoute">If true, Record-Route header field will be added.</param>
        /// <param name="forkingMode">Specifies how proxy context must handle forking.</param>
        /// <param name="isB2BUA">Specifies if proxy context is in B2BUA or just transaction satefull mode.</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="targets">Possible remote targets. NOTE: These values must be in priority order !</param>
        /// <param name="credentials">Target set credentials.</param>
        /// <exception cref="ArgumentNullException">Is raised when any of the reference type prameters is null.</exception>
        /// <exception cref="ArgumentException">Is raised when any of the arguments has invalid value.</exception>
        internal SIP_ProxyContext(SIP_ProxyCore proxy,SIP_ServerTransaction transaction,SIP_Request request,bool addRecordRoute,SIP_ForkingMode forkingMode,bool isB2BUA,bool noCancel,bool noRecurse,SIP_ProxyTarget[] targets,NetworkCredential[] credentials)
        {
            if(proxy == null){
                throw new ArgumentNullException("proxy");
            }
            if(transaction == null){
                throw new ArgumentNullException("transaction");
            }
            if(request == null){
                throw new ArgumentNullException("request");
            }
            if(targets == null){
                throw new ArgumentNullException("targets");
            }
            if(targets.Length == 0){
                throw new ArgumentException("Argumnet 'targets' must contain at least 1 value.");
            }

            m_pProxy = proxy;

            m_pServerTransaction = transaction;
            m_pServerTransaction.Canceled += new EventHandler(m_pServerTransaction_Canceled);
            m_pServerTransaction.Disposed += new EventHandler(m_pServerTransaction_Disposed);

            m_pRequest       = request;
            m_AddRecordRoute = addRecordRoute;
            m_ForkingMode    = forkingMode;
            m_IsB2BUA        = isB2BUA;
            m_NoCancel       = noCancel;
            m_NoRecurse      = noRecurse;

            m_pTargetsHandlers = new List<TargetHandler>();
            m_pResponses       = new List<SIP_Response>();
            m_ID               = Guid.NewGuid().ToString();
            m_CreateTime       = DateTime.Now;

            // Queue targets up, higest to lowest.
            m_pTargets = new Queue<TargetHandler>();
            foreach(SIP_ProxyTarget target in targets){
                m_pTargets.Enqueue(new TargetHandler(this,target.Flow,target.TargetUri,m_AddRecordRoute,false));
            }

            m_pCredentials = new List<NetworkCredential>();
            m_pCredentials.AddRange(credentials);

            /*  RFC 3841 9.1.
                The Request-Disposition header field specifies caller preferences for
                how a server should process a request.

                Override SIP proxy default value.
            */
            foreach(SIP_t_Directive directive in request.RequestDisposition.GetAllValues()){
                if(directive.Directive == SIP_t_Directive.DirectiveType.NoFork){
                    m_ForkingMode = SIP_ForkingMode.None;
                }
                else if(directive.Directive == SIP_t_Directive.DirectiveType.Parallel){
                    m_ForkingMode = SIP_ForkingMode.Parallel;
                }
                else if(directive.Directive == SIP_t_Directive.DirectiveType.Sequential){
                    m_ForkingMode = SIP_ForkingMode.Sequential;
                }
                else if(directive.Directive == SIP_t_Directive.DirectiveType.NoCancel){
                    m_NoCancel = true;
                }
                else if(directive.Directive == SIP_t_Directive.DirectiveType.NoRecurse){
                    m_NoRecurse = true;
                }
            }

            m_pProxy.Stack.Logger.AddText("ProxyContext(id='" + m_ID + "') created.");
        }