internal DextopRemoteMethodCallResult ExecuteMethodCall(DextopRemoteMethodCall call)
		{
			try
			{
				if (call.RemoteId == null)
					throw new InvalidDextopRemoteMethodCallException();

				RemotableContext context;
				if (!remotables.TryGetValue(call.RemoteId, out context))
					throw new InvalidDextopRemoteMethodCallException();

                DextopRemoteMethodInvokeResult result;
				result = DextopApplication.RemoteMethodInvoker.Invoke(context.Remotable, call.MethodName, call.Arguments, call.FormSubmit);
				if (result.Success)
					return new DextopRemoteMethodCallResult
					{
						success = true,
						result = result.Result
					};

				var map = context.Remotable.Remote.OnMapRemotingException ?? MapRemotingException;
                
                var mappedEx = map(result.Exception);
                if (mappedEx is Exception) 
                    mappedEx = MapRemotingException((Exception)mappedEx);

				return new DextopRemoteMethodCallResult
				{
					success = false,
                    result = mappedEx
				};
			}
			catch (Exception ex)
			{
				object res;
				try
				{
					res = MapRemotingException(ex);
				}
				catch (Exception mex)
				{
					res = new DextopRemoteMethodCallException
					{
						exception = mex.Message,
						stackTrace = mex.StackTrace
					};
				}
				return new DextopRemoteMethodCallResult
				{
					success = false,
					result = res
				};
			}
		}
        internal IList<Response> HandleRemotingRequest(HttpContext context, Request[] requests)
        {
            if (Culture != null)
                Thread.CurrentThread.CurrentCulture = Culture;

            HttpContext = context;

            var responses = new List<Response>();
            foreach (var request in requests)
            {

                /* This part blocks out of order processing of direct transactions for 2 seconds.
                 * This is important as two sequential http request can come in different order than sent.
                 * Luckily Ext.direct has tid field.
                 */
                int waitCounter = 20;
                while (request.tid > lastTid + 1 && --waitCounter>0)
                {
                    Thread.Sleep(100);
                }

                if (request.tid > lastTid)
                    lastTid = request.tid;

                var call = new DextopRemoteMethodCall
                {
                    FormSubmit = request.FormSubmit,
                    RemoteId = request.data[0],
                    Arguments = DextopUtil.Decode<String[]>(request.data[2]),
                    MethodName = request.data[1]
                };
                var response = new Response
                {
                    type = "rpc",
                    method = request.method,
                    tid = request.tid,
                    action = request.action
                };
                responses.Add(response);
                try
                {
                    response.result = ExecuteMethodCall(call);
                }
                catch (Exception ex)
                {
                    response.result = new DextopRemoteMethodCallResult
                    {
                        success = false,
                        result = new DextopRemoteMethodCallException
                        {
                            type = "rpc",
                            exception = ex.Message,
                            stackTrace = ex.StackTrace
                        }
                    };
                }
            }

            HttpContext = null;

            return responses;
        }