/// <summary>
        /// Create variables, generate non-overlap constraints.
        /// </summary>
        /// <param name="hPad">horizontal node padding</param>
        /// <param name="vPad">vertical node padding</param>
        /// <param name="cHPad">horizontal cluster padding</param>
        /// <param name="cVPad">vertical cluster padding</param>
        /// <param name="nodeCenter"></param>
        internal void Initialize(double hPad, double vPad, double cHPad, double cVPad, InitialCenterDelegateType nodeCenter) {
            // For the Vertical ConstraintGenerator, Padding is vPad and PadddingP(erpendicular) is hPad.
            cg = new ConstraintGenerator(IsHorizontal
                                            , IsHorizontal ? hPad : vPad
                                            , IsHorizontal ? vPad : hPad
                                            , IsHorizontal ? cHPad : cVPad
                                            , IsHorizontal ? cVPad : cHPad);
            solver = new Solver();

            foreach (var filNode in nodes) {
                filNode.SetOlapNode(IsHorizontal,null);
            }
            // Calculate horizontal non-Overlap constraints.  
            if (avoidOverlaps && clusterHierarchies != null) {
                foreach (var c in clusterHierarchies) {
                    AddOlapClusters(cg, null /* OlapParentCluster */, c, nodeCenter);
                }
            }

            foreach (var filNode in nodes) {
                if (filNode.getOlapNode(IsHorizontal) == null) {
                    AddOlapNode(cg, cg.DefaultClusterHierarchy /* olapParentCluster */, filNode, nodeCenter);
                }
                filNode.getOlapNode(IsHorizontal).CreateVariable(solver);
            }
            if (avoidOverlaps && this.ConstraintLevel >= 2) {
                cg.Generate(solver, OverlapRemovalParameters);
            }
            AddStructuralConstraints();
        }
        private void AddNodesAndSolve(ConstraintGenerator generator,
                        IEnumerable<VariableDef> iterVariableDefs,
                        OverlapRemovalParameters olapParameters,
                        IEnumerable<ConstraintDef> iterConstraintDefs,
                        ref bool succeeded)
        {
            var axisName = generator.IsHorizontal ? "X" : "Y";
            var solver = generator.IsHorizontal ? this.SolverX : this.SolverY;
            foreach (VariableDef varDef in iterVariableDefs)
            {
                // Create the variable in its initial cluster.
                OverlapRemovalCluster olapClusParent = generator.DefaultClusterHierarchy;
                if (varDef.ParentClusters.Count > 0)
                {
                    olapClusParent = varDef.ParentClusters[0].Cluster;
                }
                OverlapRemovalNode newNode;
                if (generator.IsHorizontal)
                {
                    newNode = generator.AddNode(olapClusParent, varDef.IdString,
                                           varDef.DesiredPosX, varDef.DesiredPosY,
                                           varDef.SizeX, varDef.SizeY, varDef.WeightX);
                    varDef.VariableX = new OlapTestNode(newNode);
                }
                else 
                {
                    newNode = generator.AddNode(olapClusParent, varDef.IdString,
                                           varDef.DesiredPosY, varDef.VariableX.ActualPos,
                                           varDef.SizeY, varDef.SizeX, varDef.WeightY);
                    varDef.VariableY = new OlapTestNode(newNode);
                }

                // Add it to its other clusters.
                for (int ii = 1; ii < varDef.ParentClusters.Count; ++ii)
                {
                    olapClusParent = varDef.ParentClusters[ii].Cluster;
                    generator.AddNodeToCluster(olapClusParent, newNode);
                }
            }
            generator.Generate(solver, olapParameters);
            if (TestGlobals.VerboseLevel >= 3)
            {
                this.WriteLine("  {0} Constraints:", axisName);
                foreach (Constraint cst in solver.Constraints.OrderBy(cst => cst))
                {
                    this.WriteLine("    {0} {1} g {2:F5}", cst.Left.UserData, cst.Right.UserData, cst.Gap);
                }
            }

            if (null != iterConstraintDefs)
            {
                // TODO: Compare expected to actual constraints generated in solver
            }

            var solution = generator.Solve(solver, olapParameters, false /* doGenerate */);
            if (!this.VerifySolutionMembers(solution, /*iterNeighborDefs:*/ null))
            {
                succeeded = false;
            }
            if (generator.IsHorizontal)
            {
                this.SolutionX = solution;
            }
            else
            {
                this.SolutionY = solution;
            }
        }