private void TrackWorkflowInstanceRecord(WorkflowInstanceRecord workflowInstanceRecord, ActualTrace _trace)
        {
            WorkflowInstanceState workflowInstanceState = (WorkflowInstanceState)Enum.Parse(typeof(WorkflowInstanceState), workflowInstanceRecord.State);
            WorkflowInstanceTrace workflowInstanceTrace = new WorkflowInstanceTrace(workflowInstanceRecord.InstanceId, workflowInstanceRecord.WorkflowDefinitionIdentity, workflowInstanceState);

            _trace.Add(workflowInstanceTrace);
        }
Example #2
0
        async Task <object> ContinueState(SuspendState state, WorkflowInstanceState workflowstate, WorkableLogger tasklogger, IDictionary <string, object> variables, CancellationToken token)
        {
            object lastresult = null;

            if (state.Subflow != null)
            {
                WorkflowIdentifier workflow = workflowstate.Workflow;
                workflowstate.Workflow = state.Subflow.Workflow;
                lastresult             = await ContinueState(state.Subflow, workflowstate, tasklogger, variables, token);

                workflowstate.Workflow = workflow;
            }
            else
            {
                if (variables != null)
                {
                    foreach (KeyValuePair <string, object> entry in variables)
                    {
                        state.Variables[entry.Key] = entry.Value.DetermineValue(state.Variables);
                    }
                }
            }

            InstanceTransition transition = await EvaluateTransitions(state.Node, tasklogger, state.Variables, state.Node.Transitions, token);

            if (transition == null)
            {
                tasklogger.Warning("Suspend node has no transition defined for current state. Workflow ends by default.");
                return(lastresult);
            }

            return(await Execute(workflowstate, token, transition.Target, lastresult));
        }
Example #3
0
        /// <inheritdoc />
        public async Task <WorkableTask> Execute(WorkflowInstance workflow, IDictionary <string, object> arguments, bool profiling, TimeSpan?wait = null)
        {
            WorkableTask   task       = taskservice.CreateTask(WorkableType.Workflow, workflow.Id, workflow.Revision, workflow.Name, arguments);
            WorkableLogger tasklogger = new WorkableLogger(logger, task);

            try {
                task.Task = Task.Run(() => {
                    StateVariableProvider variables = new StateVariableProvider(ProcessImports(tasklogger, workflow.StartNode.Parameters?.Imports));
                    variables.Add(arguments);

                    WorkflowInstanceState workflowstate = new WorkflowInstanceState(new WorkflowIdentifier(workflow.Id, workflow.Revision, workflow.Name), tasklogger, variables, GetWorkflowInstance, this, workflow.Language, profiling);
                    return(Execute(workflowstate, task.Token.Token, workflow.StartNode));
                }).ContinueWith(t => HandleTaskResult(t, task, tasklogger));
            }
            catch (Exception e) {
                tasklogger.Error("Failed to execute workflow", e);
                task.Finished = DateTime.Now;
                task.Status   = TaskStatus.Failure;
                await taskservice.FinishTask(task.Id);
            }

            if (wait.HasValue && !task.Task.IsCompleted)
            {
                await Task.WhenAny(task.Task, Task.Delay(wait.Value));
            }

            return(task);
        }
Example #4
0
        /// <inheritdoc />
        public override async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            logparameter ??= await compiler.CompileCodeAsync(Parameters.Text, state.Language ?? ScriptLanguage.NCScript);

            state.Logger.Log(Parameters.Type, await logparameter.ExecuteAsync <string>(state.Variables, token));
            return(null);
        }
 public void Transfer(WorkflowInstanceState state, string instanceID)
 {
     base.Connection.Execute(ResourceManage.SQL_WORKFLOW_INSTANCE_UPDATE_TRANSFER, new
     {
         State      = state.ToString(),
         InstanceID = instanceID
     });
 }
Example #6
0
        /// <inheritdoc />
        public override async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            CompiledScript script = await compiler.CompileScriptAsync(Name);

            IDictionary <string, object> arguments = await Arguments.EvaluateArguments(state.Variables, token);

            state.Logger.Info($"Executing script '{script.Name}'", string.Join("\n", arguments.Select(p => $"{p.Key}: {p.Value}")));
            return(await script.Instance.ExecuteAsync(new VariableProvider(state.Variables, arguments), token));
        }
        public void Transfer(WorkflowInstanceState state, string instanceID)
        {
            using ISession session = DbFactory.OpenSession();
            WorkflowInstance instance = session.Get <WorkflowInstance>(instanceID);

            instance.State = state;
            session.Update(instance);
            session.Flush();
        }
Example #8
0
        public void Transfer(WorkflowInstanceState state, string instanceID)
        {
            string update = " UPDATE T_INSTANCE SET State=@State WHERE InstanceID=@InstanceID ";

            base.Connection.Execute(update, new
            {
                State      = state.ToString(),
                InstanceID = instanceID
            });
        }
Example #9
0
        /// <inheritdoc />
        public override Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            if (!string.IsNullOrEmpty(Parameters.Variable))
            {
                state.Variables[Parameters.Variable] = null;
            }
            SuspendState suspendstate = new SuspendState(state.Workflow, this, state.Variables, state.Language, state.Profiling);

            return(Task.FromResult((object)suspendstate));
        }
        // If the resumption didn't timed out nor aborted, but not found, it tries to return the previous response parameter if the operation was idempotent,
        // ie. throws OperationRepeatedException, or throws InvalidOperationException if the previous response is not known (didn't happen or not idempotent).
        private async Task <TResponseParameter> ResumeOperationBookmarkAsync <TResponseParameter>(string operationName, object requestResult, Type responseParameterType)
            where TResponseParameter : class
        {
            await WaitIdleAsync(Parameters.ResumeOperationTimeout);

            try
            {
                await PrepareAsync();

                if (completionState == null)
                {
                    TaskCompletionSource <TResponseParameter> taskCompletionSource = new TaskCompletionSource <TResponseParameter>();
                    BookmarkResumptionResult result = await instance.ScheduleOperationBookmarkResumptionAsync(operationName, new object[] { taskCompletionSource, requestResult });

                    WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;
                    if (result == BookmarkResumptionResult.Success)
                    {
                        try
                        {
                            activeTaskCompletionSources.Add(taskCompletionSource);
                            await instance.RunAsync();

                            return(await taskCompletionSource.Task);
                        }
                        finally
                        {
                            activeTaskCompletionSources.Remove(taskCompletionSource);
                        }
                    }
                    else
                    {
                        if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
                        {
                            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                            throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process operation '{operationName}'.");
                        }
                        else // NotFound or NotReady && Complete, though the later is also not possible at this point, completionState != null after prepare in that case
                        {
                            throw previousResponseParameterExtension.CreatePreviousResponseParameterException <TResponseParameter>(operationName, responseParameterType);
                        }
                    }
                }
                else
                {
                    throw previousResponseParameterExtension.CreatePreviousResponseParameterException <TResponseParameter>(operationName, responseParameterType);
                }
            }
            catch
            {
                // TODO shouldn't we only set idle, if RunAsync() wasn't successful and instance.WorkflowInstanceState != WorkflowInstanceState.Runnable ???
                idle.Set();
                throw;
            }
        }
 // don't use "this" to make it a real extension method, don't box enums
 public static bool ShouldSave(IdlePersistenceMode idlePersistenceMode, WorkflowInstanceState workflowInstanceState, bool isStarting)
 {
     if (workflowInstanceState == WorkflowInstanceState.Idle)
         if (isStarting)
             return idlePersistenceMode.HasFlag(IdlePersistenceMode.OnStart);
         else
             return idlePersistenceMode.HasFlag(IdlePersistenceMode.OnPersistableIdle);
     if (workflowInstanceState == WorkflowInstanceState.Complete)
         return idlePersistenceMode.HasFlag(IdlePersistenceMode.OnCompleted);
     return false;
 }
Example #12
0
        async Task <IEnumerator> CreateEnumerator(WorkflowInstanceState state, CancellationToken token)
        {
            IScript enumerationscript = await compiler.CompileCodeAsync(Parameters.Collection, state.Language ?? ScriptLanguage.NCScript);

            object collection = await enumerationscript.ExecuteAsync(state.Variables, token);

            if (!(collection is IEnumerable enumerable))
            {
                throw new WorkflowException("Can not enumerate null");
            }

            return(enumerable.GetEnumerator());
        }
Example #13
0
        private async Task ResumeReminderBookmarkAsync(string reminderName)
        {
            await WaitIdleAsync(Parameters.ResumeInfrastructureTimeout);

            try
            {
                await PrepareAsync();

                if (completionState == null)
                {
                    BookmarkResumptionResult result = await instance.ScheduleReminderBookmarkResumptionAsync(reminderName);

                    WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;
                    if (result == BookmarkResumptionResult.Success)
                    {
                        await instance.RunAsync();
                    }
                    else
                    {
                        if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
                        {
                            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                            throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process reminder '{reminderName}'.");
                        }
                        else // NotFound or NotReady && Complete, though the later is also not possible at this point, completionState != null after prepare in that case
                             // If we don't find a reminder, it's not an issue, maybe the grain/silo crashed after the reminder was created but before the workflow state was persisted,
                             // or the grain/silo crashed after persistence but before the reminder was unregistered,
                             // it will be unregistered on the next persistence event.
                             // See ReminderTable for the detailed description of the algorithm.
                        {
                            idle.Set();
                        }
                    }
                }
                else
                {
                    await grain.UnregisterReminderAsync(reminderName);

                    idle.Set();
                }
            }
            catch
            {
                // TODO shouldn't we only set idle, if RunAsync() wasn't successful and instance.WorkflowInstanceState != WorkflowInstanceState.Runnable ???
                idle.Set();
                throw;
            }
        }
Example #14
0
        /// <inheritdoc />
        public override async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            WorkflowInstance instance = await state.GetWorkflow(parameters.Name);

            WorkflowIdentifier parent = state.Workflow;

            state.Workflow = new WorkflowIdentifier(instance.Id, instance.Revision, instance.Name);
            object result = await state.WorkflowExecutor.Execute(instance, state.Logger, await Arguments.EvaluateArguments(state.Variables, token), state.Profiling, token);

            state.Workflow = parent;
            if (result is SuspendState suspend)
            {
                result = new SuspendState(state.Workflow, this, state.Variables, state.Language, state.Profiling, suspend);
            }

            return(result);
        }
Example #15
0
        /// <inheritdoc />
        public override async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            IEnumerator current = state.GetNodeData <IEnumerator>(NodeId);

            if (current == null)
            {
                state[NodeId] = current = await CreateEnumerator(state, token);
            }

            if (current.MoveNext())
            {
                state.Variables[Parameters.Item ?? "item"] = current.Current;
                return(new LoopCommand());
            }

            state.RemoveNodeData(NodeId);
            return(null);
        }
        /// <inheritdoc />
        public override async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            expression ??= await compiler.CompileCodeAsync(GenerateCode(state.Language ?? ScriptLanguage.NCScript), state.Language ?? ScriptLanguage.NCScript);

            object result = await expression.ExecuteAsync(state.Variables, token);

            if (result is Task task)
            {
                await        task;
                PropertyInfo resultproperty = task.GetType().GetProperty("Result");
                if (resultproperty != null)
                {
                    return(resultproperty.GetValue(task));
                }
                return(null);
            }

            return(result);
        }
 // don't use "this" to make it a real extension method, don't box enums
 public static bool ShouldSave(IdlePersistenceMode idlePersistenceMode, WorkflowInstanceState workflowInstanceState, bool isStarting)
 {
     if (workflowInstanceState == WorkflowInstanceState.Idle)
     {
         if (isStarting)
         {
             return(idlePersistenceMode.HasFlag(IdlePersistenceMode.OnStarting));
         }
         else
         {
             return(idlePersistenceMode.HasFlag(IdlePersistenceMode.OnPersistableIdle));
         }
     }
     if (workflowInstanceState == WorkflowInstanceState.Complete)
     {
         return(idlePersistenceMode.HasFlag(IdlePersistenceMode.OnCompleted));
     }
     return(false);
 }
Example #18
0
        private async Task ResumeReminderBookmarkAsync(string reminderName)
        {
            BookmarkResumptionResult result = await ScheduleAndRunInstanceAsync(Parameters.ResumeInfrastructureTimeout,
                                                                                () => instance.ScheduleReminderBookmarkResumptionAsync(reminderName),
                                                                                (_result) => _result == BookmarkResumptionResult.Success);

            WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;

            if (result == BookmarkResumptionResult.NotReady && workflowInstanceState != WorkflowInstanceState.Complete)
            {
                // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
                throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process reminder '{reminderName}'.");
            }
            //else // NotFound, Complete or Success
            // If we don't find a reminder, it's not an issue, maybe the grain/silo crashed after the reminder was created but before the workflow state was persisted,
            // or the grain/silo crashed after persistence but before the reminder was unregistered,
            // it will be unregistered on the next persistence event.
            // See ReminderTable for the detailed description of the algorithm.
        }
        public FinalTraceSubscription(Guid instanceId, ManualResetEvent mre, int numOccurences, bool hasPersistence, WorkflowInstanceState finalState)
        {
            this.manualResetEvent = mre;
            _numOccurences        = numOccurences;

            // If there is no persistence provider wait for the completed trace
            _expectedFinalState = finalState;

            // Also wait for the deleted
            if (hasPersistence)
            {
                _numOccurences++;
            }
            _waitingForDeleted = hasPersistence;

            _instanceId = instanceId;

            //Log.TraceInternal(String.Format("[FinalTraceSubscription]Instance {0} Waiting for {1}.", instanceId, (hasPersistence)?"Deleted":finalState.ToString()));
        }
Example #20
0
        /// <inheritdoc />
        public async Task <object> Execute(WorkflowInstanceState state, CancellationToken token)
        {
            object result = await node.Execute(state, token);

            if (operation != null)
            {
                if (result != null)
                {
                    if (!state.Variables.TryGetValue(VariableName, out object lhs))
                    {
                        lhs = result is string? "" : Activator.CreateInstance(result.GetType());
                    }
                    result = await operation.ExecuteAsync(new VariableProvider(state.Variables, new Variable("lhs", lhs), new Variable("rhs", result)), token);
                }
            }

            state.Variables[VariableName] = result;
            return(result);
        }
        public void WaitForTerminalState(WorkflowInstanceState expected, bool validate, int numOccurences)
        {
            WaitForFinalTrace(expected, numOccurences);

            if (this.ExpectedInstanceTraces == null)
            {
                this.ExpectedTraces.AddIgnoreTypes(false, typeof(WorkflowInstanceTrace));
            }

            if (validate)
            {
                if (this.ExpectedInstanceTraces == null)
                {
                    ValidateTrackingAndTracing(this.ExpectedTraces);
                }
                else
                {
                    ValidateTrackingAndTracing(this.ExpectedTraces, this.ExpectedInstanceTraces);
                }
            }
        }
Example #22
0
        /// <inheritdoc />
        public async Task <WorkableTask> Continue(Guid taskid, IDictionary <string, object> variables = null, TimeSpan?wait = null)
        {
            WorkableTask task = await taskservice.GetTask(taskid);

            if (task.Status != TaskStatus.Suspended)
            {
                throw new ArgumentException($"Task '{taskid}' is not suspended.");
            }
            if (task.SuspensionState == null)
            {
                throw new InvalidOperationException($"Task '{taskid}' has no suspension state linked to it.");
            }

            WorkableLogger tasklogger = new WorkableLogger(logger, task);

            tasklogger.Info("Resuming execution of workflow", string.Join("\n", variables?.Select(p => $"{p.Key}={p.Value}") ?? new string[0]));

            try {
                task.Status = TaskStatus.Running;
                task.Task   = Task.Run(async() => {
                    WorkflowInstanceState workflowstate = new WorkflowInstanceState(task.SuspensionState.Workflow, tasklogger, task.SuspensionState.Variables, GetWorkflowInstance, this, task.SuspensionState.Language, task.SuspensionState.Profiling);
                    return(await ContinueState(task.SuspensionState, workflowstate, tasklogger, variables, task.Token.Token));
                }).ContinueWith(t => HandleTaskResult(t, task, tasklogger));
            }
            catch (Exception e) {
                tasklogger.Error("Failed to execute workflow", e);
                task.Finished = DateTime.Now;
                task.Status   = TaskStatus.Failure;
                await taskservice.FinishTask(task.Id);
            }

            if (wait.HasValue && !task.Task.IsCompleted)
            {
                await Task.WhenAny(task.Task, Task.Delay(wait.Value));
            }

            return(task);
        }
 // Returns true if no aborted or unhandled exception
 internal void WaitForFinalTrace(WorkflowInstanceState state, int numOccurences)
 {
     // If not using the DefaultTracking configuration, then we need to wait for a user trace. The reason is that
     //  InMemoryTrackingParticipant, unlike SQL, pushed traces to the subscription. SQL however is pull only,
     //  so the subscription will hang forever. The workaround is in the Tracking tests wait for the synchronize trace
     //  since it is a user trace and we will always get it.
     if (!TestTraceManager.IsDefaultTrackingConfiguration)
     {
         WaitForSynchronizeTrace(numOccurences);
     }
     else
     {
         ManualResetEvent       mre          = new ManualResetEvent(false);
         FinalTraceSubscription subscription = new FinalTraceSubscription(_workflowInstanceId, mre, numOccurences, _hasPersistenceProvider, state);
         TestTraceManager.Instance.AddSubscription(_workflowInstanceId, subscription);
         if (!mre.WaitOne(TimeSpan.FromSeconds(TestTraceManager.MaximumNumberOfSecondsToWaitForATrace)))
         {
             throw new TimeoutException(string.Format("Waited for {0} seconds in WaitForFinalTrace without getting the expeced trace of {1}",
                                                      TestTraceManager.MaximumNumberOfSecondsToWaitForATrace, state.ToString()));
         }
         subscription.CheckIfSuccessful();
     }
 }
Example #24
0
        // If the resumption didn't timed out nor aborted, but not found, it tries to return the previous response parameter if the operation was idempotent,
        // ie. throws RepeatedOperationException, or throws InvalidOperationException if the previous response is not known (didn't happen or not idempotent).
        private async Task ResumeOperationBookmarkAsync <TResponseParameter>(string operationName, TaskCompletionSource <TResponseParameter> taskCompletionSource, object requestResult, Type responseParameterType,
                                                                             Func <object, RepeatedOperationException> createRepeatedOperationException)
            where TResponseParameter : class
        {
            BookmarkResumptionResult result = await ScheduleAndRunInstanceAsync(Parameters.ResumeOperationTimeout,
                                                                                () => instance.ScheduleOperationBookmarkResumptionAsync(operationName, new object[] { taskCompletionSource, requestResult }),
                                                                                (_result) => _result == BookmarkResumptionResult.Success,
                                                                                taskCompletionSource);

            WorkflowInstanceState workflowInstanceState = instance.WorkflowInstanceState;

            if (result == BookmarkResumptionResult.NotFound ||
                result == BookmarkResumptionResult.NotReady && workflowInstanceState == WorkflowInstanceState.Complete)
            {
                previousResponseParameterExtension.ThrowPreviousResponseParameter(operationName, responseParameterType, createRepeatedOperationException);
            }
            else if (result == BookmarkResumptionResult.NotReady) // && !Complete
            // Instance is created but the initialization RunAsync() hasn't been called, this is impossible.
            {
                throw new InvalidOperationException($"Instance state is '{workflowInstanceState}', instance is not ready to process operation '{operationName}'.");
            }
            //else // Success
        }
 public WorkflowInstanceTrace(Guid instanceName, WorkflowIdentity workflowDefintionIdentity, WorkflowInstanceState instanceStatus)
 {
     _instanceName              = instanceName;
     _instanceStatus            = instanceStatus;
     _workflowDefintionIdentity = workflowDefintionIdentity;
 }
 public WorkflowInstanceTrace(Guid instanceName, WorkflowInstanceState instanceStatus) :
     this(instanceName, null, instanceStatus)
 {
 }
 public WorkflowInstanceTrace(WorkflowIdentity workflowDefintionIdentity, WorkflowInstanceState instanceStatus) :
     this(Guid.Empty, workflowDefintionIdentity, instanceStatus)
 {
 }
 public WorkflowInstanceTrace(WorkflowInstanceState instanceStatus) :
     this(Guid.Empty, null, instanceStatus)
 {
 }
        public static void Trace(Guid workflowInstanceId, WorkflowIdentity workflowDefinitionIdentity, WorkflowInstanceState state)
        {
            WorkflowInstanceTrace trace = new WorkflowInstanceTrace(workflowInstanceId, workflowDefinitionIdentity, state);

            TraceSource ts = new TraceSource("CoreWf.Tracking", SourceLevels.Information);

            ts.TraceData(TraceEventType.Information, 1, trace);
        }
 /// <summary>
 /// Constructor with instance id and state.
 /// </summary>
 /// <param name="id">The workflow Id.</param>
 /// <param name="state">The state of workflow</param>
 /// <param name="unhandledException">The unhandled exception, occurs when streams are closed.</param>
 internal WorkflowStatusEventArgs(Guid id, WorkflowInstanceState state, Exception unhandledException)
 {
     this.id = id;
     this.state = state;
     this.unhandledException = unhandledException;
 }
Example #31
0
        public WorkflowHandlingResponse StartWorkflow(
            WorkflowStartInfo startInfo)
        {
            WorkflowFindData workflowFindData = new WorkflowFindData()
            {
                StartType = startInfo.StartType,
                Code      = startInfo.Code
            };
            WorkflowInfo wfInfo = this.FindWorkflow(workflowFindData);

            if (wfInfo == null)
            {
                throw new WorkflowException(string.Format("workflow with code: '{0}' not found", (object)workflowFindData.Code));
            }
            using (UnitOfWork unitOfWork = new UnitOfWork((IDataContextAsync) new WorkflowDbContext()))
            {
                WorkflowStep workflowStep = unitOfWork.RepositoryAsync <WorkflowStep>().Queryable(false, true, (List <Expression <Func <WorkflowStep, object> > >)null).Where <WorkflowStep>((Expression <Func <WorkflowStep, bool> >)(wfStep => (int)wfStep.StepType == 1 && wfStep.WorkflowInfoId == wfInfo.ID)).SingleOrDefault <WorkflowStep>();
                if (workflowStep == null)
                {
                    throw new WorkflowException(string.Format("no start step for workflow with code '{0}'", (object)startInfo.Code));
                }
                int?nullable = startInfo.StarterOrganizationId;
                if (!nullable.HasValue && SecurityManager.CurrentUserContext != null)
                {
                    startInfo.StarterOrganizationId = SecurityManager.CurrentUserContext.OrganizationId;
                }
                if (startInfo.ExchangeData == null)
                {
                    startInfo.ExchangeData = new WFExchangeData();
                }
                List <WorkflowInstanceState> workflowInstanceStateList = new List <WorkflowInstanceState>();
                WorkflowInstanceState        workflowInstanceState1    = new WorkflowInstanceState();
                workflowInstanceState1.AccomplishTime    = new DateTime?(DateTime.Now);
                workflowInstanceState1.ExchangeData      = (string)startInfo.ExchangeData;
                workflowInstanceState1.InstantiationTime = DateTime.Now;
                workflowInstanceState1.ObjectState       = ObjectState.Added;
                nullable = new int?();
                workflowInstanceState1.SenderWorkflowInstanceStateId = nullable;
                workflowInstanceState1.UserComment    = "شروع فرایند";
                workflowInstanceState1.StateStatus    = WfStateStatus.Close;
                workflowInstanceState1.Title          = string.Format("شروع فرایند {0} {1}", (object)wfInfo.Title, (object)startInfo.InstanceTitle);
                workflowInstanceState1.UserId         = startInfo.StarterUserId;
                workflowInstanceState1.WorkflowStepId = workflowStep.ID;
                WorkflowInstanceState workflowInstanceState2 = workflowInstanceState1;
                workflowInstanceStateList.Add(workflowInstanceState2);
                WFExchangeData wfExchangeData1 = new WFExchangeData();
                WFExchangeData wfExchangeData2 = wfExchangeData1;
                nullable = startInfo.StarterOrganizationId;
                ref int?local1 = ref nullable;
                int     num;
                string  str1;
                if (!local1.HasValue)
                {
                    str1 = (string)null;
                }
                else
                {
                    num  = local1.GetValueOrDefault();
                    str1 = num.ToString();
                }
                wfExchangeData2.Add("_StarterOrganizationId_", str1);
                WFExchangeData wfExchangeData3 = wfExchangeData1;
                num = startInfo.StarterUserId;
                string str2 = num.ToString();
                wfExchangeData3.Add("_StarterUserId_", str2);
                wfExchangeData1.Add("_InstanceTitle_", string.Format("{0}", (object)startInfo.InstanceTitle));
                wfExchangeData1.Add("_WorkflowTitle_", string.Format("{0}", (object)wfInfo.Title));
                wfExchangeData1.Add("_RelatedRecordId_", string.Format("{0}", (object)startInfo.RelatedRecordId));
                bool                  flag                = false;
                WorkflowStep          currentStep         = workflowStep;
                WFExchangeData        exchangeData        = startInfo.ExchangeData;
                WorkflowInstanceState senderInstanceState = workflowInstanceState2;
                WFExchangeData        initialExchangeData = wfExchangeData1;
                nullable = new int?();
                int?     actionId = nullable;
                ref bool local2   = ref flag;
        private void AddWorkflowInstanceTrace(TraceEventType eventType, Guid instanceId, WorkflowIdentity workflowDefintionIdentity, WorkflowInstanceState instanceStatus)
        {
            WorkflowInstanceTrace trace = new WorkflowInstanceTrace(instanceId, workflowDefintionIdentity, instanceStatus);

            this.TestTraceManager.AddTrace(instanceId, trace);
            if (workflowDefintionIdentity != null)
            {
                TestTraceManager.OptionalLogTrace(string.Format("[TestTrackingParticipantBase]{0} : {1} : {2,-11} : {3}", instanceId, workflowDefintionIdentity, eventType, instanceStatus));
            }
            else
            {
                TestTraceManager.OptionalLogTrace(string.Format("[TestTrackingParticipantBase]{0} : {1,-11} : {2}", instanceId, eventType, instanceStatus));
            }
        }