void ProcessRecursive(IActionContainer parentContext, SecurityContext parentSecurityContext, ActionItem actionGroup, List <ActionItem> actions, ExecuteResult parentResult, Dictionary <string, string> dynamicData, bool dryRun, Func <SecurityContext, ActionItem, Dictionary <string, string>, object, bool, ExecuteResult> executeHandlerMethod) { if (WantsStopOrPause()) { return; } parentContext.EnsureInitialized(); //queryStatus provides the inbound value to ExecuteCase evaluation; it's the ExecuteCase comparison value. //queryStatus is carried downward through successive subtree executions. StatusType queryStatus = parentResult.Status; #region actionGroup if (actionGroup != null && (((actionGroup.ExecuteCase & parentResult.Status) == actionGroup.ExecuteCase) || (actionGroup.ExecuteCase == StatusType.Any))) { actionGroup.EnsureInitialized(); #region actionGroup-forEach if ((actionGroup.HasParameters && actionGroup.Parameters.HasForEach) || (actionGroup.Handler.HasConfig && actionGroup.Handler.Config.HasForEach)) { List <ActionItem> resolvedParmsActionGroup = new List <ActionItem>(); ResolveConfigAndParameters(actionGroup, dynamicData, ref resolvedParmsActionGroup, parentResult.ExitData); foreach (ActionItem ai in resolvedParmsActionGroup) { ai.Parameters.ForEach = null; } actionGroup.InstanceId = ActionInstanceIdCounter++; ActionItem agclone = actionGroup.Clone(); agclone.Result = new ExecuteResult(); parentContext.ActionGroup = agclone; Parallel.ForEach(resolvedParmsActionGroup, a => // foreach( ActionItem a in resolvedParmsActionGroup ) { #if sqlite a.CreateInstance(parentContext, InstanceId); #endif a.InstanceId = ActionInstanceIdCounter++; ActionItem clone = a.Clone(); agclone.Actions.Add(clone); ExecuteResult r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun); parentContext.ActionGroup.Result.SetBranchStatusChecked(r); parentContext.Result.SetBranchStatusChecked(r); clone.Handler.Type = actionGroup.Handler.Type; clone.Handler.StartInfo = actionGroup.Handler.StartInfo; clone.Result = r; if (r.Status > queryStatus) { queryStatus = r.Status; } if (a.HasActions) { ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod); parentContext.ActionGroup.Result.SetBranchStatusChecked(clone.Result); parentContext.Result.SetBranchStatusChecked(clone.Result); if (clone.Result.Status > queryStatus) { queryStatus = clone.Result.Status; } } }); } #endregion #region actionGroup-single else { #if sqlite actionGroup.CreateInstance(parentContext, InstanceId); #endif ResolveConfigAndParameters(actionGroup, dynamicData, parentResult.ExitData); actionGroup.InstanceId = ActionInstanceIdCounter++; ActionItem clone = actionGroup.Clone(); parentContext.ActionGroup = clone; ExecuteResult r = executeHandlerMethod(parentSecurityContext, actionGroup, dynamicData, parentResult.ExitData, dryRun); parentContext.Result.SetBranchStatusChecked(r); clone.Handler.Type = actionGroup.Handler.Type; clone.Handler.StartInfo = actionGroup.Handler.StartInfo; clone.Result = r; if (r.Status > queryStatus) { queryStatus = r.Status; } if (actionGroup.HasActions) { ProcessRecursive(clone, actionGroup.RunAs, null, actionGroup.Actions, r, dynamicData, dryRun, executeHandlerMethod); parentContext.Result.SetBranchStatusChecked(clone.Result); if (clone.Result.Status > queryStatus) { queryStatus = clone.Result.Status; } } } #endregion } #endregion #region actions IEnumerable <ActionItem> actionList = actions.Where(a => (((a.ExecuteCase & queryStatus) == a.ExecuteCase) || (a.ExecuteCase == StatusType.Any))); List <ActionItem> resolvedParmsActions = new List <ActionItem>(); Parallel.ForEach(actionList, a => // foreach( ActionItem a in actionList ) ResolveConfigAndParameters(a, dynamicData, ref resolvedParmsActions, parentResult.ExitData) ); Parallel.ForEach(resolvedParmsActions, a => // foreach( ActionItem a in resolvedParmsActions ) { #if sqlite a.CreateInstance(parentContext, InstanceId); #endif a.InstanceId = ActionInstanceIdCounter++; ActionItem clone = a.Clone(); parentContext.Actions.Add(clone); ExecuteResult r = a.Result; if (r?.Status != StatusType.Failed) { r = executeHandlerMethod(parentSecurityContext, a, dynamicData, parentResult.ExitData, dryRun); } parentContext.Result.SetBranchStatusChecked(r); clone.Handler.Type = a.Handler.Type; clone.Handler.StartInfo = a.Handler.StartInfo; clone.Result = r; if (a.HasActions) { ProcessRecursive(clone, a.RunAs, a.ActionGroup, a.Actions, r, dynamicData, dryRun, executeHandlerMethod); parentContext.Result.SetBranchStatusChecked(clone.Result); } }); #endregion }