/// <summary>
        /// Begins a New Search corresponding with the <see cref="Solver"/> and
        /// <paramref name="agent"/>.
        /// </summary>
        /// <param name="agent"></param>
        /// <returns></returns>
        protected virtual ISearchAgent NewSearch(ISearchAgent agent)
        {
            agent.ProcessVariables -= OnProcessVariables;
            agent.ProcessVariables += OnProcessVariables;

            return(agent.NewSearch(a => a.Solver.MakePhase(a.Variables, IntVarSimple, IntValueSimple)));
        }
        /// <summary>
        /// Begins a New Search corresponding with the <see cref="Solver"/> and
        /// <paramref name="agent"/>.
        /// </summary>
        /// <param name="agent"></param>
        /// <returns></returns>
        /// <inheritdoc />
        protected override ISearchAgent NewSearch(ISearchAgent agent)
        {
            agent.ProcessVariables -= OnProcessVariables;
            agent.ProcessVariables += OnProcessVariables;

            // The simple strategies are okay and yield expected results. But let's keep it interesting.
            return(agent.NewSearch(a => a.Solver.MakePhase(a.Variables, ChooseRandom, AssignRandomValue)));
        }
        // TODO: TBD: PrepareSearchMonitors is perhaps closer to a fluent style...

        /// <summary>
        /// Override to prepare the <see cref="SearchMonitor"/> or monitors for the
        /// <paramref name="agent"/> and corresponding <see cref="Solver"/>. If called, the base
        /// method should be called after preparing any other required Monitors. By default, a
        /// single <see cref="SolutionCollector"/> is prepared.
        /// </summary>
        /// <param name="agent"></param>
        /// <param name="variables"></param>
        /// <returns></returns>
        protected virtual ISearchAgent PrepareSearchMonitors(ISearchAgent agent, params IntVar[] variables)
        {
            if (!agent.HasSolutionCollector <SolutionCollector>())
            {
                // Start with a single all-solution-collector.
                agent.Monitor(a =>
                {
                    var m    = a.Solver.MakeAllSolutionCollector();
                    var vect = new IntVarVector().TrackClrObject(this);
                    foreach (var v in variables)
                    {
                        vect.Add(v);
                    }
                    m.Add(vect);
                    return(m);
                });
            }

            return(agent);
        }
        // "Creating" a new SearchAgent here was not buying us much that we shouldn't just create it when it was called.

        // TODO: TBD: a bit on the fence about the prospect of a "for-each-solution"; could make for an interesting API, but is it necessary?

        /// <summary>
        ///
        /// </summary>
        /// <param name="agent"></param>
        /// <param name="handler"></param>
        /// <returns></returns>
        public static ISearchAgent ForEachSolution(this ISearchAgent agent, EventHandler <ProcessVariablesEventArgs> handler)
        {
            agent.ProcessVariables += handler;
            return(agent);
        }