public Signal Manipulate(Signal rootSignal, IManipulationVisitor visitor, bool ignoreHold) { IScanStrategy allPathsStrat = Binder.GetSpecificInstance <IScanStrategy>(new MathIdentifier("AllPathsStrategy", "Traversing")); Dictionary <Guid, ManipulationPlan> plans = new Dictionary <Guid, ManipulationPlan>(); Dictionary <Guid, Signal> signalReplacements = new Dictionary <Guid, Signal>(); Dictionary <Guid, Signal> sentinels = new Dictionary <Guid, Signal>(); // ## ESTIMATE MANIPULATION PLAN _scanner.ForEachPort(rootSignal, delegate(Port p) { if (!plans.ContainsKey(p.InstanceId)) { plans.Add(p.InstanceId, visitor.EstimatePlan(p)); } return(true); }, ignoreHold); // ## OPTIMIZE MANIPULATION PLAN (cycle analysis) ManipulatorPlanReducer reducer = new ManipulatorPlanReducer(plans, ignoreHold); allPathsStrat.Traverse(rootSignal, reducer, ignoreHold); // ## EXECUTE MANIPULATION ManipulatorPlanExecutor executor = new ManipulatorPlanExecutor(plans, signalReplacements, sentinels, visitor); allPathsStrat.Traverse(rootSignal, executor, ignoreHold); // ## SELECT NEW SYSTEM Signal ret; if (!signalReplacements.TryGetValue(rootSignal.InstanceId, out ret)) { ret = rootSignal; } // ## FIX SENTINELS ON SELECTED NEW SYSTEM _scanner.ForEachPort(ret, delegate(Port p) { // look for sentinels on all input signals ReadOnlySignalSet inputs = p.InputSignals; for (int i = 0; i < inputs.Count; i++) { Signal input = inputs[i]; if (FixSentinel(ref input, sentinels, signalReplacements)) { p.ReplaceInputSignalBinding(i, input); } } return(true); }, ignoreHold); FixSentinel(ref ret, sentinels, signalReplacements); // ## RETURN SELECTED NEW SYSTEM AS RESULT return(ret); }