/// <summary>
        ///     Responsible for the processing of all inbound requests
        ///     This method is reentrant and will call itself to
        ///     for every invocation required in every generation
        ///     of nesting. e.g services made up of services
        /// </summary>
        /// <param name="resourceDirectory">The singleton instance of the service library that contains all the logical services</param>
        /// <param name="xmlRequest">The actual client request message</param>
        /// <param name="dataListId">The id of the data list</param>
        /// <param name="errors">Errors resulting from this invoke</param>
        /// <returns></returns>
        public Guid Invoke(IDynamicServicesHost resourceDirectory, dynamic xmlRequest, Guid dataListId,
                           out ErrorResultTO errors)
        {
            // Host = resourceDirectory

            #region Async processing of client request - queue the work item asynchronously

            //Get an UnlimitedObject from the xml string provided by the caller
            //TraceWriter.WriteTraceIf(_managementChannel != null && _loggingEnabled, "Inspecting inbound data request", Resources.TraceMessageType_Message);
            Guid result = GlobalConstants.NullDataListID;

            var allErrors = new ErrorResultTO();
            errors = new ErrorResultTO();

            if(xmlRequest.Async is string)
            {
                //TraceWriter.WriteTrace(_managementChannel, "Caller requested async execution");
                bool isAsync;

                bool.TryParse(xmlRequest.Async, out isAsync);

                if(isAsync)
                {
                    ThreadPool.QueueUserWorkItem(delegate
                    {
                        ErrorResultTO tmpErrors;
                        //TraceWriter.WriteTrace(_managementChannel, "Queuing Asynchronous work", Resources.TraceMessageType_Message);
                        xmlRequest.RemoveElementByTagName("Async");
                        IDynamicServicesInvoker invoker = new DynamicServicesInvoker(_dsfChannel, _managementChannel);
                        result = invoker.Invoke(resourceDirectory, xmlRequest, dataListId, out tmpErrors);
                        if(tmpErrors.HasErrors())
                        {
                            allErrors.MergeErrors(tmpErrors);
                        }
                        //TraceWriter.WriteTrace(result.XmlString);
                        if(result != GlobalConstants.NullDataListID)
                        {
                            // PBI : 5376
                            SvrCompiler.DeleteDataListByID(result, true); //TODO: Clean it up ;)
                        }
                    });
                    dynamic returnData = new UnlimitedObject();
                    returnData.Load(string.Format("<ServiceResponse>{0} Work Item Queued..</ServiceResponse>",
                                                  DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss.fff")));
                    return returnData;
                }
            }

            #endregion

            #region Get a handle on the service that is being requested from the service directory

            string serviceName = string.Empty;

            //Set the service name as this is a complex message
            //with multiple services requests embedded in the inbound data
            //This will allow us to 
            if(xmlRequest.Service is IEnumerable<UnlimitedObject>)
            {
                IEnumerable<UnlimitedObject> services = xmlRequest.Service;
                dynamic serviceData = services.First();
                if(serviceData.Service is string)
                {
                    serviceName = serviceData.Service;
                }
            }


            //If there is only a single service request then get the service name
            if(xmlRequest.Service is string)
            {
                serviceName = xmlRequest.Service;
            }

            //If the service name does not exist return an error to the caller
            if(string.IsNullOrEmpty(serviceName))
            {
                xmlRequest.Error = Resources.DynamicServiceError_ServiceNotSpecified;
            }

            //Try to retrieve the service from the service directory

            IEnumerable<DynamicService> service;
            Host.LockServices();

            try
            {
                service = from c in resourceDirectory.Services
                          where serviceName != null
                          && c.Name.Trim().Equals(serviceName.Trim(), StringComparison.CurrentCultureIgnoreCase)
                          select c;
            }
            finally
            {
                Host.UnlockServices();
            }

            service = service.ToList();

            if(!service.Any())
            {
                TraceWriter.WriteTrace(_managementChannel, string.Format("Service '{0}' Not Found", serviceName),
                                       Resources.TraceMessageType_Error);

                allErrors.AddError(string.Format("Service '{0}' Not Found", serviceName));

                throw new InvalidOperationException(string.Format("Service '{0}' Not Found", serviceName));

                //xmlRequest.Error = Resources.DynamicServiceError_ServiceNotFound;
            }

            #endregion

            //Instantiate a Dynamic Invocation type to invoke the service

            #region  Transactionalized Service Invocation with support for MS-DTC

            dynamic dseException = null;

            //The transactionScope is used to create an ambient transaction that every action will be subject to
            //This transaction 
            try
            {
                //TraceWriter.WriteTrace(_managementChannel, string.Format("Setting up transaction scope", serviceName), Resources.TraceMessageType_Message);
                using(var transactionScope = new TransactionScope())
                {
                    //TraceWriter.WriteTrace(_managementChannel, string.Format("Invoking Service '{0}'", serviceName), Resources.TraceMessageType_Message);

                    #region Process several requests to different services as a single unit of work

                    //Type 3 request (read above)
                    //This is handled differently to type 1 and 2 requests
                    //as it can execute in the context of either a single or 
                    //multiple services.
                    //if (xmlRequest.IsMultipleRequests) {
                    //    TraceWriter.WriteTrace(_managementChannel, "Caller requested multiple service execution in single request", Resources.TraceMessageType_Message);
                    //    dynamic results = new UnlimitedObject();

                    //    foreach (dynamic request in xmlRequest.Requests) {

                    //        dynamic result = new DynamicServicesInvoker(_dsfChannel, _managementChannel).Invoke(resourceDirectory, request);
                    //        if (result.HasError) {
                    //            return result;
                    //        }
                    //        results.AddResponse(result);
                    //    }
                    //    transactionScope.Complete();

                    //    return results;
                    //}

                    #endregion

                    DynamicService s = service.First();
                    result = Invoke(s, xmlRequest, dataListId, out errors);
                    if(result == GlobalConstants.NullDataListID)
                    {
                        allErrors.AddError("Failed to invoke service");
                 
                    }
                    
                    if(!ClientCompiler.HasErrors(result))
                    {
                        transactionScope.Complete();
                    }

                    //The service exists so invoke the service which runs all actions defined for the service
                    //Return the response
                    //return xmlResponses;
                }
            }
            //Occurs when an operation is attempted on a rolled back transaction
            catch(TransactionAbortedException abortEx)
            {
                dseException = abortEx;
            }
            //This exception is thrown when an action is attempted on a transaction that is in doubt. 
            //A transaction is in doubt when the state of the transaction cannot be determined. 
            //Specifically, the final outcome of the transaction, whether it commits or aborts, is never known for this transaction.
            catch(TransactionInDoubtException inDoubtEx)
            {
                dseException = inDoubtEx;
            }
            //Thrown when a resource manager cannot communicate with the transaction manager. 
            catch(TransactionManagerCommunicationException transactionManagerEx)
            {
                dseException = transactionManagerEx;
            }
            //Thrown when a promotion fails
            catch(TransactionPromotionException promotionException)
            {
                dseException = promotionException;
            }
            catch(TransactionException transactionEx)
            {
                dseException = transactionEx;
            }

            if(dseException != null)
            {
                TraceWriter.WriteTrace(_managementChannel,
                                       string.Format("Service Execution Failed With Error\r\n{0}",
                                                     new UnlimitedObject(dseException).XmlString),
                                       Resources.TraceMessageType_Error);
            }

            // set error variable
            errors = allErrors;
            if(errors.HasErrors())
            {
                DispatchDebugState(xmlRequest, dataListId, allErrors);
            }

            return result;

            #endregion
        }