void IServerChannelSink.AsyncProcessResponse(IServerResponseChannelSinkStack sinkStack, object state, IMessage msg, ITransportHeaders headers, System.IO.Stream stream)
        {
#if DEBUG
            System.Diagnostics.Trace.Assert((state as System.Threading.Thread).Equals(System.Threading.Thread.CurrentThread));
#endif
            sinkStack.AsyncProcessResponse(msg, headers, stream);
            ServerAuthenticationHelper.UnAuthenticate();
        }
        ServerProcessing IServerChannelSink.ProcessMessage(IServerChannelSinkStack sinkStack, IMessage requestMsg, ITransportHeaders requestHeaders, System.IO.Stream requestStream, out IMessage responseMsg, out ITransportHeaders responseHeaders, out System.IO.Stream responseStream)
        {
            System.Net.IPAddress address = System.Net.IPAddress.Parse(requestHeaders[CommonTransportKeys.IPAddress].ToString());
            if (!IsTrustedIP(address))
            {
                Logger.Error("Client connection refused from  " + address.ToString());
                throw new SC.Interfaces.SCException("Connection refused from address " + address.ToString());
            }

            if (ServerAuthenticationHelper.IsChallengeRequest(requestHeaders))
            {
                Logger.Info("Client connection accepted from " + address.ToString());
                ClientContext context = new ClientContext();

                responseHeaders = new TransportHeaders();
                responseStream  = new System.IO.MemoryStream();

                context.AuthHelper.Challenge(responseHeaders);
                responseMsg = requestMsg;

                lock (contexts)
                    contexts[context.AuthHelper.Ticket] = context;

                return(ServerProcessing.Complete);
            }
            if (!AuthenticationHelper.HasValidTicket(requestHeaders))
            {
                throw new SC.Interfaces.SCException("Protocol violation: No ticket");
            }

            Guid ticket = AuthenticationHelper.GetTicket(requestHeaders);

            ClientContext ctxt = null;

            lock (contexts)
            {
                if (contexts.ContainsKey(ticket))
                {
                    ctxt = contexts[ticket];
                }
            }

            if (ctxt == null)
            {
                throw new SC.Interfaces.SCException("Protocol violation: issue a challenge request first.");
            }
            else if (ctxt.SessionExpired)
            {
                Logger.Info("Session for address " + address.ToString() + " expired.");
                throw new SC.Interfaces.SessionExpiredException();
            }

            ctxt.AuthHelper.Authenticate(requestHeaders, ref requestStream);
            ServerProcessing result = nextSink.ProcessMessage(sinkStack, requestMsg, requestHeaders, requestStream, out responseMsg, out responseHeaders, out responseStream);

            if (result == ServerProcessing.Async)
            {
                sinkStack.Push(this,
#if DEBUG
                               System.Threading.Thread.CurrentThread
#else
                               null
#endif
                               );
            }
            else
            {
                ServerAuthenticationHelper.UnAuthenticate();
            }
            return(result);
        }