internal SolverContext Save(string path)
            {
                CpModel model;

                if (!Monitors.Any())
                {
                    model = Solver.ExportModel();
                }
                else if (DecisionBuilder == null)
                {
                    using (var vector = new SearchMonitorVector())
                    {
                        foreach (var m in Monitors)
                        {
                            vector.Add(m);
                        }
                        model = Solver.ExportModelWithSearchMonitors(vector);
                    }
                }
                else
                {
                    using (var vector = new SearchMonitorVector())
                    {
                        foreach (var m in Monitors)
                        {
                            vector.Add(m);
                        }
                        model = Solver.ExportModelWithSearchMonitorsAndDecisionBuilder(vector, DecisionBuilder);
                    }
                }

                using (var ws = File.Open(path, Create))
                {
                    Assert.NotNull(model);
                    model.WriteTo(ws);
                }

                return(this);
            }
            internal SolverContext Load(string path)
            {
                var model = new CpModel();

                using (var ms = File.Open(path, Open))
                {
                    model.MergeFrom(ms);
                }

                // TODO: TBD: careful that ModelLoader is disposable...
                Assert.That(Solver.ModelLoader(), Is.Null);

                if (Monitors.Any())
                {
                    using (var vector = new SearchMonitorVector())
                    {
                        foreach (var monitor in Monitors)
                        {
                            vector.Add(monitor);
                        }

                        Assert.That(Solver.LoadModelWithSearchMonitors(model, vector), Is.True);
                    }
                }
                else
                {
                    // TODO: TBD: or s.LoadModelWithSearchMonitors; which also implies that somehow the model has been at least prepared, with variables, monitors, and/or decision builder
                    Assert.That(Solver.LoadModel(model), Is.True);
                }

                var loader = Solver.ModelLoader();

                Assert.That(loader, Is.Not.Null);

                return(this);
            }
        public void SimpleTestWithSearchMonitorsAndDecisionBuilder()
        {
            CpModel model;

            string modelText;

            const string modelName    = "TestModelLoader";
            const string equationText = "((x(0..10) + y(0..10)) == 5)";

            using (var s = new Solver(modelName))
            {
                var x = s.MakeIntVar(0, 10, "x");
                var y = s.MakeIntVar(0, 10, "y");
                var c = x + y == 5;
                Assert.That(c.Cst.ToString(), Is.EqualTo(equationText));
                s.Add(c);
                Assert.That(s.ConstraintCount(), Is.EqualTo(1));
                var collector = s.MakeAllSolutionCollector();
                var db        = s.MakePhase(x, y, ChooseFirstUnbound, AssignMinValue);
                Console.WriteLine("First search...");
                s.NewSearch(db, collector);
                while (s.NextSolution())
                {
                    Console.WriteLine($"{x.ToString()} + {y.ToString()} == 5");
                    break;
                }
                s.EndSearch();
                using (var vect = new SearchMonitorVector())
                {
                    vect.Add(collector);
                    model     = s.ExportModelWithSearchMonitorsAndDecisionBuilder(vect, db);
                    modelText = model.ToString();
                }
            }

            using (var s = new Solver(modelName))
            {
                // TODO: TBD: load but without any monitors and/or DB ...
                s.LoadModel(model);

                var loader = s.ModelLoader();
                // Do a quick sanity check that we at least have the proper constraint loaded.
                Assert.That(s.ConstraintCount(), Is.EqualTo(1));

                var x = loader.IntegerExpressionByName("x").Var();
                var y = loader.IntegerExpressionByName("y").Var();

                {
                    var c = x + y == 5;
                    // These should PASS as well...
                    Assert.That(c.Cst.ToString(), Is.Not.EqualTo("TrueConstraint()"));
                    Assert.That(c.Cst.ToString(), Is.EqualTo(equationText));
                }

                {
                    /* I dare say that THIS should PASS as well, but due to the fact that IntVar and
                     * derivatives are treated as IntExpr, it is FAILING. */
                    var actual = s.ExportModel();
                    Assert.That(actual.ToString(), Is.EqualTo(modelText));
                }

                var db = s.MakePhase(x, y, ChooseFirstUnbound, AssignMinValue);
                Console.WriteLine("Second search...");
                s.NewSearch(db);
                while (s.NextSolution())
                {
                    Console.WriteLine($"{x.ToString()} + {y.ToString()} == 5");
                }
                s.EndSearch();
            }
        }