/// <summary> Handle a request msg for this correlator
		/// 
		/// </summary>
		/// <param name="req">the request msg
		/// </param>
		private void  handleRequest(Message req,Address replyTo)
		{
			object retval;
			byte[] rsp_buf = null;
			HDR hdr, rsp_hdr;
			Message rsp;
			
			// i. Remove the request correlator header from the msg and pass it to
			// the registered handler
			//
			// ii. If a reply is expected, pack the return value from the request
			// handler to a reply msg and send it back. The reply msg has the same
			// ID as the request and the name of the sender request correlator
			hdr = (HDR) req.removeHeader(HeaderType.REQUEST_COORELATOR);
			
			if(NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleRequest()", "calling (" + (request_handler != null?request_handler.GetType().FullName:"null") + ") with request " + hdr.id);

            TimeStats appTimeStats = null;
            bool isProfilable = false;
			try
			{

                if (hdr.rsp_expected)
                    req.RequestId = hdr.id;
                else
                    req.RequestId = -1;

                if (req.HandledAysnc)
                {
                    request_handler.handle(req);
                    return;
                }
                if (hdr.type == HDR.GET_REQ_STATUS)
                {
                    if(NCacheLog.IsInfoEnabled) NCacheLog.Info("ReqCorrelator.handleRequet", hdr.status_reqId + " receive RequestStatus request from " + req.Src);
                    retval = GetRequestStatus(hdr.status_reqId, req.Src);
                    if (NCacheLog.IsInfoEnabled) NCacheLog.Info("ReqCorrelator.handleRequet", hdr.status_reqId + " RequestStatus :" + retval);
                }
                else
                {
                    MarkRequestArrived(hdr.id, req.Src);
                    retval = request_handler.handle(req);
                }

                //request is being handled asynchronously, so response will be send by
                //the the user itself.
                
			}
			catch (System.Exception t)
			{
				NCacheLog.Error("RequestCorrelator.handleRequest()", "error invoking method, exception=" + t.ToString());
				retval = t;
			}

            if (!hdr.rsp_expected || stopReplying)
                // asynchronous call, we don't need to send a response; terminate call here
                return;
			
			if (transport == null)
			{
				NCacheLog.Error("RequestCorrelator.handleRequest()", "failure sending " + "response; no transport available");
				return ;
			}

            rsp = req.makeReply();
            if (replyTo != null) rsp.Dest = replyTo;
			// changed (bela Feb 20 2004): catch exception and return exception
			try
			{
                if (retval is OperationResponse)
                {
                    rsp_buf = (byte[]) ((OperationResponse)retval).SerializablePayload;
                    rsp.Payload = ((OperationResponse)retval).UserPayload;
                    rsp.responseExpected = true;
                }
                else if(retval is Byte[])
					rsp_buf = (byte[])retval;
				else
					rsp_buf = CompactBinaryFormatter.ToByteBuffer(retval,null); // retval could be an exception, or a real value
			}
			catch (System.Exception t)
			{
				NCacheLog.Error("RequestCorrelator.handleRequest()", t.ToString());
				try
				{
					rsp_buf = CompactBinaryFormatter.ToByteBuffer(t,null); // this call shoudl succeed (all exceptions are serializable)
				}
				catch (System.Exception)
				{
					NCacheLog.Error("RequestCorrelator.handleRequest()", "failed sending response: " + "return value (" + retval + ") is not serializable");
					return ;
				}
			}

            if (rsp_buf != null)
				rsp.setBuffer(rsp_buf);

            if (rsp.Dest.Equals(local_addr))
            {                
                //we need not to put our response on the stack.
                rsp.Src = local_addr;
                ReceiveLocalResponse(rsp,hdr.id);
                return;
            }
            
            rsp_hdr = new HDR();
            rsp_hdr.type = HDR.RSP;
            rsp_hdr.id = hdr.id;
            rsp_hdr.rsp_expected = false;


			rsp.putHeader(HeaderType.REQUEST_COORELATOR, rsp_hdr);
			
			if(NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleRequest()", "sending rsp for " + rsp_hdr.id + " to " + rsp.Dest);
						
			try
			{
               
                if (transport is Protocol)
                {
                    
                    Event evt = new Event();
                    evt.Type = Event.MSG;
                    evt.Arg = rsp;
                    ((Protocol)transport).passDown(evt);
                }
                else if (transport is Transport)
                    ((Transport)transport).send(rsp);
                else
                    NCacheLog.Error("RequestCorrelator.handleRequest()", "transport object has to be either a " + "Transport or a Protocol, however it is a " + transport.GetType());
			}
			catch (System.Exception e)
			{
				NCacheLog.Error("RequestCorrelator.handleRequest()", e.ToString());
			}
            MarkRequestProcessed(hdr.id, req.Src);
		}
        private void handleStatusRequest(Message req)
        {
            object retval;
            byte[] rsp_buf = null;
            HDR hdr, rsp_hdr;
            Message rsp;

            // i. Remove the request correlator header from the msg and pass it to
            // the registered handler
            //
            // ii. If a reply is expected, pack the return value from the request
            // handler to a reply msg and send it back. The reply msg has the same
            // ID as the request and the name of the sender request correlator
            hdr = (HDR)req.removeHeader(HeaderType.REQUEST_COORELATOR);

            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleStatusRequest()", "calling (" + (request_handler != null ? request_handler.GetType().FullName : "null") + ") with request " + hdr.id);


            if (transport == null)
            {
                NCacheLog.Error("RequestCorrelator.handleStatusRequest()", "failure sending " + "response; no transport available");
                return;
            }
            RequestStatus status = GetRequestStatus(hdr.id, req.Src);

            rsp_hdr = new HDR();
            rsp_hdr.type = HDR.GET_REQ_STATUS_RSP;
            rsp_hdr.id = hdr.id;
            rsp_hdr.rsp_expected = false;
            rsp_hdr.reqStatus = status;

            rsp = req.makeReply();
            rsp.putHeader(HeaderType.REQUEST_COORELATOR, rsp_hdr);

            if (rsp.Dest.Equals(local_addr))
            {
                //we need not to put our response on the stack.
                rsp.Src = local_addr;
                ReceiveLocalResponse(rsp, hdr.id);
                return;
            }

            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleStatusRequest()", "sending rsp for " + rsp_hdr.id + " to " + rsp.Dest);

            try
            {

                if (transport is Protocol)
                {
                    
                    Event evt = new Event();
                    evt.Type = Event.MSG;
                    evt.Arg = rsp;
                    ((Protocol)transport).passDown(evt);
                }
                else if (transport is Transport)
                    ((Transport)transport).send(rsp);
                else
                    NCacheLog.Error("RequestCorrelator.handleStatusRequest()", "transport object has to be either a " + "Transport or a Protocol, however it is a " + transport.GetType());
            }
            catch (System.Exception e)
            {
                NCacheLog.Error("RequestCorrelator.handleStatusRequest()", e.ToString());
            }
        }
        /// <summary> Handle a request msg for this correlator
        /// 
        /// </summary>
        /// <param name="req">the request msg
        /// </param>
        private void handleNHopRequest(Message req)
        {
            object retval = null;
            byte[] rsp_buf = null;
            HDR hdr, rsp_hdr, replicaMsg_hdr;
            Message rsp;

            Address destination = null;
            Message replicationMsg = null;

            // i. Remove the request correlator header from the msg and pass it to
            // the registered handler
            //
            // ii. If a reply is expected, pack the return value from the request
            // handler to a reply msg and send it back. The reply msg has the same
            // ID as the request and the name of the sender request correlator
            hdr = (HDR)req.removeHeader(HeaderType.REQUEST_COORELATOR);

            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleNHopRequest()", "calling (" + (request_handler != null ? request_handler.GetType().FullName : "null") + ") with request " + hdr.id);

            try
            {
                if (hdr.rsp_expected)
                    req.RequestId = hdr.id;
                else
                    req.RequestId = -1;

                if (req.HandledAysnc)
                {
                    request_handler.handle(req);
                    return;
                }
                if (hdr.type == HDR.NHOP_REQ)
                {
                    MarkRequestArrived(hdr.id, req.Src);
                    retval = request_handler.handleNHopRequest(req, out destination, out replicationMsg);
                }
            }
            catch (System.Exception t)
            {
                NCacheLog.Error("RequestCorrelator.handleNHopRequest()", "error invoking method, exception=" + t.ToString());
                retval = t;
            }

            if (!hdr.rsp_expected || stopReplying)
                return;

            if (transport == null)
            {
                NCacheLog.Error("RequestCorrelator.handleNHopRequest()", "failure sending " + "response; no transport available");
                return;
            }

            //1. send request to other replica.
            //   this node will send the response to original node.
            if (replicationMsg != null)
            {
                replicaMsg_hdr = new HDR();
                replicaMsg_hdr.type = HDR.REQ;
                replicaMsg_hdr.id = hdr.id;
                replicaMsg_hdr.rsp_expected = true;
                replicaMsg_hdr.whomToReply = req.Src;

                replicationMsg.Dest = destination;
                replicationMsg.putHeader(HeaderType.REQUEST_COORELATOR, replicaMsg_hdr);

                try
                {
                    if (transport is Protocol)
                    {
                        Event evt = new Event();
                        evt.Type = Event.MSG;
                        evt.Arg = replicationMsg;
                        ((Protocol)transport).passDown(evt);
                    }
                    else if (transport is Transport)
                        ((Transport)transport).send(replicationMsg);
                    else
                        NCacheLog.Error("RequestCorrelator.handleRequest()", "transport object has to be either a " + "Transport or a Protocol, however it is a " + transport.GetType());
                }
                catch (System.Exception e)
                {
                    NCacheLog.Error("RequestCorrelator.handleRequest()", e.ToString());
                }
            }
            
            //2. send reply back to original node
            //   and inform the original node that it must expect another response 
            //   from the replica node. (the response of the request sent in part 1)
            rsp = req.makeReply();

            try
            {
                if (retval is OperationResponse)
                {
                    rsp_buf = (byte[])((OperationResponse)retval).SerializablePayload;
                    rsp.Payload = ((OperationResponse)retval).UserPayload;
                    rsp.responseExpected = true;
                }
                else if (retval is Byte[])
                    rsp_buf = (byte[])retval;
                else
                    rsp_buf = CompactBinaryFormatter.ToByteBuffer(retval, null); // retval could be an exception, or a real value
            }
            catch (System.Exception t)
            {
                NCacheLog.Error("RequestCorrelator.handleRequest()", t.ToString());
                try
                {
                    rsp_buf = CompactBinaryFormatter.ToByteBuffer(t, null); // this call shoudl succeed (all exceptions are serializable)
                }
                catch (System.Exception)
                {
                    NCacheLog.Error("RequestCorrelator.handleRequest()", "failed sending response: " + "return value (" + retval + ") is not serializable");
                    return;
                }
            }

            if (rsp_buf != null)
                rsp.setBuffer(rsp_buf);

            rsp_hdr = new HDR();
            rsp_hdr.type = HDR.NHOP_RSP;
            rsp_hdr.id = hdr.id;
            rsp_hdr.rsp_expected = false;

            if (replicationMsg != null)
            {
                rsp_hdr.expectResponseFrom = destination;
            }
            
            rsp.putHeader(HeaderType.REQUEST_COORELATOR, rsp_hdr);

            if (NCacheLog.IsInfoEnabled) NCacheLog.Info("RequestCorrelator.handleRequest()", "sending rsp for " + rsp_hdr.id + " to " + rsp.Dest);

            try
            {
                if (transport is Protocol)
                {
                    Event evt = new Event();
                    evt.Type = Event.MSG;
                    evt.Arg = rsp;
                    ((Protocol)transport).passDown(evt);
                }
                else if (transport is Transport)
                    ((Transport)transport).send(rsp);
                else
                    NCacheLog.Error("RequestCorrelator.handleRequest()", "transport object has to be either a " + "Transport or a Protocol, however it is a " + transport.GetType());
            }
            catch (System.Exception e)
            {
                NCacheLog.Error("RequestCorrelator.handleRequest()", e.ToString());
            }

            MarkRequestProcessed(hdr.id, req.Src);
        }