public void RecordTaskActionHandler(RecordTaskAction message)
        {
            var workflowId = message.WorkflowInstanceId;
            var tenantId = message.TenantId;
            var auditContext = message.AuditContext;
            var objId = message.TargetObjectId;
            var objType = message.TargetObjectType;
            var taskEvent = message.Event;
            var task = message.State + "|" + message.Task;
            var state = message.State;
            var workflowName = message.WorkflowTemplateName;
            var stateNameForLock = (string.IsNullOrEmpty(state) ? message.StateId.ToString() : state);
            var stateLock = new StateLock()
            {
                WorkflowInstanceId = workflowId,
                WorkflowInstanceTenantId = tenantId,
                StateName = stateNameForLock,
            };
            while (lockedStates.Exists(x => x.WorkflowInstanceId == workflowId && x.StateName == stateNameForLock && x.WorkflowInstanceTenantId == tenantId))
            {
                System.Threading.Thread.Sleep(100);
            }
            lockedStates.Add(stateLock);
            try
            {
                //System.Console.WriteLine("Event Received : " + taskEvent);
                WorkflowInstance data = null;
                using (var dataContext = new DataContext(message.TenantId, auditContext))
                {

                    try
                    {
                        data = Utils.GetWorkflowInstance(dataContext, workflowId, objId, objType);
                        if (data == null)
                        {
                            return;
                        }
                        var stateData = data.States.Where(x => (x.Id == message.StateId)).FirstOrDefault();
                        if (stateData == null)
                        {
                            stateData = data.States.Where(x => (x.StateTemplate.StateName == message.State)).OrderByDescending(x => x.Id).FirstOrDefault();
                            if (stateData == null)
                            {
                                return;
                            }
                        }
                        var taskData = stateData.Tasks.Where(x => (x.Id == message.TaskId)).FirstOrDefault();
                        if (taskData == null)
                        {
                            taskData = stateData.Tasks.Where(x => (x.TaskTemplate.TaskName == task)).OrderByDescending(x => x.Id).FirstOrDefault();
                            if (taskData == null)
                            {
                                return;
                            }
                        }
                        var eventData = data.WorkflowTemplate.EventsTypes.FirstOrDefault(x => x.ParentName == taskData.TaskTemplate.TaskName && x.Event == taskEvent && x.Type == EventType.EventLevel.TASK);
                        if (eventData == null)
                        {
                            return;
                        }
                        var workflowEvent = new WorkflowEvent()
                        {
                            EventDate = DateTime.UtcNow,
                            EventMetaData = null,
                            EventType = eventData,
                            ExecutedBy = auditContext,
                            TaskParent = taskData,
                            WorkflowInstance = data,
                        };
                        data.Events.Add(workflowEvent);

                        if (data.CurrentState.Id == stateData.Id && taskData.IsCurrentTask == true)
                        {
                            TaskTemplate nextTaskTemplate = stateData.StateTemplate.Tasks.FirstOrDefault(x => x.TaskName == eventData.MoveTo);
                            if (nextTaskTemplate == null)
                            {
                                return;
                            }
                            taskData.IsCurrentTask = false;
                            PocketBoss.Models.Task newTask = new Models.Task()
                            {
                                TaskTemplate = nextTaskTemplate,
                                IsCurrentTask = true,
                                LastTask = nextTaskTemplate.LastTask,
                                State = stateData,
                                WorkflowInstance = data,
                                TransitionDate = DateTime.UtcNow,
                                TransitionedBy = auditContext,
                                TransitionEvent = workflowEvent,
                            };
                            stateData.Tasks.Add(newTask);
                            dataContext.SaveChanges();
                            publishNewTasks(data, newTask, message.AuditContext, message.TenantId, _bus);
                        }
                    }
                    catch (Exception exc)
                    {
                    }

                }
                using (var dataContext = new DataContext(message.TenantId, auditContext))
                {
                    if (dataContext.Tasks.Count(x => x.LastTask == false && x.IsCurrentTask == true && x.State.IsCurrent == true && x.WorkflowInstanceId == data.Id) == 0)
                    {
                        updateStateAsComplete(data, message.AuditContext, message.TenantId, _bus);
                    }
                }
            }
            catch (Exception exc)
            {
            }
            finally
            {
                lockedStates.Remove(stateLock);
            }
        }
        public void RecordStateActionHandler(RecordStateAction message)
        {
            var workflowId = message.WorkflowInstanceId;
            var tenantId = message.TenantId;
            var auditContext = message.AuditContext;
            var objId = message.TargetObjectId;
            var objType = message.TargetObjectType;
            var stateEvent = message.Event;
            var state = message.State;

            using (var dataContext = new DataContext(message.TenantId, message.AuditContext))
            {
                try
                {
                    var data = Utils.GetWorkflowInstance(dataContext, workflowId, objId, objType);
                    var transition = data.WorkflowTemplate.EventsTypes.FirstOrDefault(x => x.Event == stateEvent && ((x.Type == EventType.EventLevel.GLOBAL) || (x.Type == EventType.EventLevel.STATE && x.ParentName == state)));

                    data = Utils.GetWorkflowInstance(dataContext, workflowId, objId, objType);
                    if (data == null)
                    {
                        return;
                    }
                    var stateData = data.States.Where(x => (x.Id == message.StateId)).FirstOrDefault();
                    if (stateData == null)
                    {
                        stateData = data.States.Where(x => (x.StateTemplate.StateName == message.State)).OrderByDescending(x => x.Id).FirstOrDefault();
                        if (stateData == null)
                        {
                            return;
                        }
                    }

                    WorkflowEvent newEvent = null;

                    if (transition != null)
                    {
                        newEvent = new WorkflowEvent()
                        {
                            EventDate = DateTime.UtcNow,
                            EventMetaData = null,
                            EventType = transition,
                            WorkflowInstance = data,
                            ExecutedBy = message.AuditContext,
                        };
                        if (transition.Type == EventType.EventLevel.GLOBAL)
                        {
                            newEvent.WorkflowParent = data;
                        }
                        else
                        {
                            newEvent.StateParent = stateData;
                        }
                        data.Events.Add(newEvent);
                    }
                    else
                    {
                        return;
                    }
                    if (data.CurrentState.Id == stateData.Id || data.WorkflowTemplate.EventsTypes.Count(x => x.Type == EventType.EventLevel.GLOBAL && x.Event == stateEvent) > 0)
                    {
                        if (transition != null)
                        {
                            var nextState = data.WorkflowTemplate.States.FirstOrDefault(x => x.StateName == transition.MoveTo);
                            if (nextState != null)
                            {

                                var previousState = data.CurrentState;
                                data.CurrentState.IsCurrent = false;
                                data.CurrentState = new State()
                                {
                                    LastState = nextState.LastState,
                                    MetaData = null,
                                    TransitionDate = DateTime.UtcNow,
                                    TransitionedBy = auditContext,
                                    TransitionEvent = newEvent,
                                    Tasks = new List<Models.Task>(),
                                    StateTemplate = nextState,
                                };
                                data.CurrentState.StateTemplate.Tasks.Where(x => x.FirstTask == true).ToList().ForEach(x =>
                                {
                                    data.CurrentState.Tasks.Add(new Models.Task()
                                    {
                                        IsCurrentTask = true,
                                        State = data.CurrentState,
                                        TaskTemplate = x,
                                        TransitionDate = DateTime.UtcNow,
                                        TransitionedBy = message.AuditContext,
                                        WorkflowInstance = data,
                                        LastTask = x.LastTask,
                                    });
                                }
                                );
                            }
                            data.Completed = data.CurrentState.LastState;
                            if (data.Completed)
                            {
                                data.EndDate = DateTime.UtcNow;
                            }
                            dataContext.SaveChanges();
                            Utils.PublishWorkflowState(_bus, data, message.AuditContext);
                            Utils.PublishNewTasks(_bus, data, message.AuditContext);

                        }
                    }
                    else
                    {
                        dataContext.SaveChanges();
                    }
                }
                catch (Exception exc)
                {
                }
            }
        }