/// <summary>
        /// Handles the response to a setup message.
        /// </summary>
        /// <param name="message">A response message.</param>
        private void HandleResponseToSetup(RtspResponse message)
        {
            RtspRequest original = message.OriginalRequest;
            string      setupKey = original.SourcePort.RemoteAdress + "SEQ" + message.CSeq.ToString(CultureInfo.InvariantCulture);

            if (message.IsOk)
            {
                Forwarder forwarder = ConfigureTransportAndForwarder(message, _setupForwarder[setupKey]);

                RtspSession newSession;
                string      sessionKey = RtspSession.GetSessionName(original.RtspUri, message.Session);
                if (_activesSession.ContainsKey(sessionKey))
                {
                    newSession = _activesSession[sessionKey];
                    _logger.Info("There was an already a session with ths ID {0}", newSession.Name);
                }
                else
                {
                    _logger.Info("Create a new session with the ID {0}", sessionKey);
                    newSession             = new RtspSession();
                    newSession.Name        = message.Session;
                    newSession.Destination = original.RtspUri.Authority;
                    _activesSession.Add(sessionKey, newSession);
                }

                newSession.AddForwarder(original.RtspUri, forwarder);
                newSession.Timeout = message.Timeout;
            }
            // No needed here anymore.
            _setupForwarder.Remove(setupKey);
        }
        /// <summary>
        /// Handles the request play.
        /// Do not forward message if already playing
        /// </summary>
        /// <param name="destination">The destination.</param>
        /// <param name="requestPlay">The request play.</param>
        /// <returns>The message to transmit</returns>
        private RtspMessage HandleRequestPlay(ref RtspListener destination, RtspRequestPlay requestPlay)
        {
            Contract.Requires(requestPlay != null);
            Contract.Requires(destination != null);
            Contract.Ensures(Contract.Result <RtspMessage>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out destination) != null);


            string sessionKey = RtspSession.GetSessionName(requestPlay.RtspUri, requestPlay.Session);

            if (_activesSession.ContainsKey(sessionKey))
            {
                RtspSession session = _activesSession[sessionKey];

                // si on est dèjà en play on n'envoie pas la commande a la source.
                if (session.State == RtspSession.SessionState.Playing)
                {
                    session.Start(requestPlay.SourcePort.RemoteAdress);
                    RtspResponse returnValue = requestPlay.CreateResponse();
                    destination = requestPlay.SourcePort;
                    return(returnValue);
                }

                // ajoute un client
                session.Start(requestPlay.SourcePort.RemoteAdress);
            }
            return(requestPlay);
        }
        /// <summary>
        /// Updates the state of the session.
        /// </summary>
        /// <param name="message">A response message.</param>
        private void UpdateSessionState(RtspResponse message)
        {
            // if no session can be found
            if (message.OriginalRequest == null ||
                (message.Session == null && message.OriginalRequest.Session == null) ||
                message.OriginalRequest.RtspUri == null)
            {
                return;
            }

            // voir a mettre dans la message....
            string curentSession = message.Session != null ? message.Session : message.OriginalRequest.Session;



            //Update session state and handle special message
            string sessionKey = RtspSession.GetSessionName(message.OriginalRequest.RtspUri, curentSession);

            if (_activesSession.ContainsKey(sessionKey))
            {
                if (message.ReturnCode >= 300 && message.ReturnCode < 400)
                {
                    _activesSession[sessionKey].State = RtspSession.SessionState.Init;
                }
                else if (message.ReturnCode < 300)
                {
                    switch (message.OriginalRequest.RequestTyped)
                    {
                    case RtspRequest.RequestType.SETUP:
                        if (_activesSession[sessionKey].State == RtspSession.SessionState.Init)
                        {
                            _activesSession[sessionKey].State = RtspSession.SessionState.Ready;
                        }
                        break;

                    case RtspRequest.RequestType.PLAY:
                        if (_activesSession[sessionKey].State == RtspSession.SessionState.Ready)
                        {
                            _activesSession[sessionKey].State = RtspSession.SessionState.Playing;
                        }
                        break;

                    case RtspRequest.RequestType.RECORD:
                        if (_activesSession[sessionKey].State == RtspSession.SessionState.Ready)
                        {
                            _activesSession[sessionKey].State = RtspSession.SessionState.Recording;
                        }
                        break;

                    case RtspRequest.RequestType.PAUSE:
                        if (_activesSession[sessionKey].State == RtspSession.SessionState.Playing ||
                            _activesSession[sessionKey].State == RtspSession.SessionState.Recording)
                        {
                            _activesSession[sessionKey].State = RtspSession.SessionState.Ready;
                        }
                        break;

                    case RtspRequest.RequestType.TEARDOWN:
                        _activesSession[sessionKey].State = RtspSession.SessionState.Init;

                        break;
                    }
                }
            }
            else
            {
                _logger.Warn("Command {0} for session {1} which was not found", message.OriginalRequest.RequestTyped, sessionKey);
            }
        }
        /// <summary>
        /// Handles request message.
        /// </summary>
        /// <param name="message">A message, can be rewriten.</param>
        /// <returns>The destination</returns>
        private RtspListener HandleRequest(ref RtspMessage message)
        {
            Contract.Requires(message != null);
            Contract.Requires(message is RtspRequest);
            Contract.Ensures(Contract.Result <RtspListener>() != null);
            Contract.Ensures(Contract.ValueAtReturn(out message) != null);


            RtspRequest request = message as RtspRequest;

            RtspListener destination;

            // Do not forward, direct respond because we do not know where to send.
            if (request.RtspUri == null || request.RtspUri.AbsolutePath.Split(new char[] { '/' }, 3).Length < 3)
            {
                destination = HandleRequestWithoutUrl(ref message);
            }
            else
            {
                try
                {
                    // get the real destination
                    request.RtspUri = RewriteUri(request.RtspUri);
                    destination     = GetRtspListenerForDestination(request.RtspUri);

                    // Handle setup
                    RtspRequestSetup requestSetup = request as RtspRequestSetup;
                    if (requestSetup != null)
                    {
                        message = HandleRequestSetup(ref destination, requestSetup);
                    }

                    //Handle Play Reques
                    RtspRequestPlay requestPlay = request as RtspRequestPlay;
                    if (requestPlay != null)
                    {
                        message = HandleRequestPlay(ref destination, requestPlay);
                    }



                    //Update session state and handle special message
                    if (request.Session != null && request.RtspUri != null)
                    {
                        string sessionKey = RtspSession.GetSessionName(request.RtspUri, request.Session);
                        if (_activesSession.ContainsKey(sessionKey))
                        {
                            _activesSession[sessionKey].Handle(request);
                            switch (request.RequestTyped)
                            {
                            // start here to start early
                            //case RtspRequest.RequestType.PLAY:
                            // _activesSession[sessionKey].Start(request.SourcePort.RemoteAdress);
                            //   break;
                            case RtspRequest.RequestType.TEARDOWN:
                                _activesSession[sessionKey].Stop(request.SourcePort.RemoteAdress);
                                if (!_activesSession[sessionKey].IsNeeded)
                                {
                                    _activesSession.Remove(sessionKey);
                                }
                                else
                                {
                                    // system still need the server to send data do not send him the message.
                                    // reponds to client directly.
                                    destination = request.SourcePort;
                                    message     = request.CreateResponse();
                                }
                                break;
                            }
                        }
                        else
                        {
                            _logger.Warn("Command {0} for session {1} which was not found", request.RequestTyped, sessionKey);
                        }
                    }
                }
                catch (Exception error)
                {
                    _logger.Error("Error during handle of request", error);
                    destination = request.SourcePort;
                    RtspResponse theDirectResponse = request.CreateResponse();
                    theDirectResponse.ReturnCode = 500;
                    message = theDirectResponse;
                }
            }

            return(destination);
        }