/// <summary>
        /// It is called when SQL batch request arrives
        /// </summary>
        /// <param name="message">TDS message recieved</param>
        /// <returns>TDS message to respond with</returns>
        public override TDSMessageCollection OnSQLBatchRequest(ITDSServerSession session, TDSMessage request)
        {
            // Delegate to the base class to produce the response first
            TDSMessageCollection batchResponse = base.OnSQLBatchRequest(session, request);

            // Check if arguments are of routing server
            if (Arguments is RoutingTDSServerArguments)
            {
                // Cast to routing server arguments
                RoutingTDSServerArguments ServerArguments = Arguments as RoutingTDSServerArguments;

                // Check routing condition
                if (ServerArguments.RouteOnPacket == TDSMessageType.SQLBatch)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", routingToken);

                    // Insert the routing token at the beginning of the response
                    batchResponse[0].Insert(0, routingToken);
                }
                else
                {
                    // Get the first response message
                    TDSMessage responseMessage = batchResponse[0];

                    // Reset the content of the first message
                    responseMessage.Clear();

                    // Prepare ERROR token with the denial details
                    responseMessage.Add(new TDSErrorToken(11111, 1, 14, "Client should have been routed by now", Arguments.ServerName));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[0]);

                    // Prepare DONE token
                    responseMessage.Add(new TDSDoneToken(TDSDoneTokenStatusType.Final | TDSDoneTokenStatusType.Error));

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", responseMessage[1]);
                }
            }

            // Register only one message with the collection
            return(batchResponse);
        }
        /// <summary>
        /// Complete login sequence
        /// </summary>
        protected override TDSMessageCollection OnAuthenticationCompleted(ITDSServerSession session)
        {
            // Delegate to the base class
            TDSMessageCollection responseMessageCollection = base.OnAuthenticationCompleted(session);

            // Check if arguments are of routing server
            if (Arguments is RoutingTDSServerArguments)
            {
                // Cast to routing server arguments
                RoutingTDSServerArguments serverArguments = Arguments as RoutingTDSServerArguments;

                // Check routing condition
                if (serverArguments.RouteOnPacket == TDSMessageType.TDS7Login)
                {
                    // Construct routing token
                    TDSPacketToken routingToken = CreateRoutingToken();

                    // Log response
                    TDSUtilities.Log(Arguments.Log, "Response", routingToken);

                    // Get the first message
                    TDSMessage targetMessage = responseMessageCollection[0];

                    // Index at which to insert the routing token
                    int insertIndex = targetMessage.Count - 1;

                    // VSTS# 1021027 - Read-Only Routing yields TDS protocol error
                    // Resolution: Send TDS FeatureExtAct token before TDS ENVCHANGE token with routing information
                    TDSPacketToken featureExtAckToken = targetMessage.Find(t => t is TDSFeatureExtAckToken);

                    // Check if found
                    if (featureExtAckToken != null)
                    {
                        // Find token position
                        insertIndex = targetMessage.IndexOf(featureExtAckToken);
                    }

                    // Insert right before the done token
                    targetMessage.Insert(insertIndex, routingToken);
                }
            }

            return(responseMessageCollection);
        }