private void ActivityChanged(ProcessActivityChangedEventArgs args, WorkflowRuntime runtime)
        {
            if (!args.TransitionalProcessWasCompleted)
            {
                return;
            }

            Log.Information($":::::::::: ActivityChanged: pid={args.ProcessId.ToString()}, scheme={args.SchemeCode}, activity={args.CurrentActivityName}, state={args.CurrentState}, last={args.PreviousState}");
            WorkflowProductService.TransitionType transitionType = GetTransitionType(args);
            var serviceArgs = new WorkflowProductService.ProductActivityChangedArgs
            {
                ProcessId            = args.ProcessId,
                CurrentActivityName  = args.CurrentActivityName,
                PreviousActivityName = args.PreviousActivityName,
                CurrentState         = args.CurrentState,
                PreviousState        = args.PreviousState,
                ExecutingCommand     = args.ProcessInstance.CurrentCommand,
                TransitionType       = transitionType
            };

            BackgroundJob.Enqueue <WorkflowProductService>(service => service.ProductActivityChanged(serviceArgs));
        }
        private WorkflowProductService.TransitionType GetTransitionType(ProcessActivityChangedEventArgs args)
        {
            WorkflowProductService.TransitionType transitionType = WorkflowProductService.TransitionType.Other;
            // In DWKit 2.4.1, when executing a timeout transition back to the same state,
            // args.ExecutedTransition isn't the transition that is actually being executed
            // (seems to be the first transition of all defined).  In this case, ignore the
            // transition type.
            if (args.ExecutedTransition != null)
            {
                if ((args.CurrentState == args.ExecutedTransition.To.State) && (args.PreviousState == args.ExecutedTransition.From.State))
                {
                    switch (args.ExecutedTransition.Classifier)
                    {
                    case TransitionClassifier.Direct:
                        transitionType = WorkflowProductService.TransitionType.Continuation;
                        break;

                    case TransitionClassifier.Reverse:
                        transitionType = (args.ExecutedTransition.Trigger.Type == TriggerType.Command)
                                ? WorkflowProductService.TransitionType.Rejection
                                : WorkflowProductService.TransitionType.Reverse;
                        break;

                    default:
                        transitionType = WorkflowProductService.TransitionType.Other;
                        break;
                    }
                }
                else
                {
                    Log.Warning($":::: Executing Transition Mismatch: PreviousState={args.PreviousState}=>CurrentState={args.CurrentState}; TransitionName={args.ExecutedTransition.Name}, From={args.ExecutedTransition.From.State} => To={args.ExecutedTransition.To.State}");
                }
            }

            return(transitionType);
        }