@Override
  public void add(ReconfigurationProblem rp) {
    List<DemandingSlice> dSlices = new ArrayList<DemandingSlice>(rp.getDemandingSlices());

    Collections.sort(
        dSlices, new SliceComparator(false, SliceComparator.ResourceType.cpuConsumption));

    int[][] sizes = new int[2][];
    sizes[0] = new int[dSlices.size()];
    sizes[1] = new int[dSlices.size()];

    IntDomainVar[] assigns = new IntDomainVar[dSlices.size()];
    for (int i = 0; i < dSlices.size(); i++) {
      sizes[0][i] = dSlices.get(i).getCPUheight();
      sizes[1][i] = dSlices.get(i).getMemoryheight();
      assigns[i] = dSlices.get(i).hoster();
    }

    Node[] ns = rp.getNodes();
    IntDomainVar[][] capas = new IntDomainVar[2][];
    capas[0] = new IntDomainVar[ns.length];
    capas[1] = new IntDomainVar[ns.length];

    for (int i = 0; i < ns.length; i++) {
      capas[0][i] = rp.getFreeCPU(ns[i]);
      capas[1][i] = rp.getFreeMem(ns[i]);
    }

    pack = new FastMultiBinPacking(rp.getEnvironment(), capas, sizes, assigns);
    rp.post(pack);

    Plan.logger.debug("SatisfyDemandingSlicesHeightsCustomBP branched");
  }
  // select the node state variable in order
  @Override
  public IntDomainVar selectVar() {
    //    	 ManagedElementSet<VirtualMachine> allVMS =
    // pb.getSourceConfiguration().getAllVirtualMachines();
    //         IntDomainVar[] hosters = new IntDomainVar[allVMS.size()];
    //         for(int i = 0; i < allVMS.size(); i++) {
    //             VirtualMachine vm = pb.getVirtualMachine(i);
    //             hosters[i] = pb.getAssociatedAction(vm).getDemandingSlice().hoster();
    //             if(hosters[i].isInstantiated()) {
    //             	log.debug("hoster " + i + " instancied " + hosters[i].getVal());
    //             } else {
    //             	log.debug("hoster " + i + " not instancied ");
    //             }
    //         }

    for (int i = 0; i < nodes.size(); i++) {
      Node n = nodes.get(i);

      // future online and future offline should have their state set already
      if (!pb.getFutureOnlines().contains(n) && !pb.getFutureOfflines().contains(n)) {
        ManageableNodeActionModel action = (ManageableNodeActionModel) pb.getAssociatedAction(n);
        log.debug("Node " + n.getName());
        log.debug("state instancied " + action.getState().isInstantiated());
        // Select the empty nodes first
        if (!action.getState().isInstantiated() && pb.getUsedMem(n).isInstantiatedTo(0)) {
          log.debug("select node " + n.getName() + " for switch off");
          return action.getState();
        }
        if (pb.getUsedMem(n).isInstantiatedTo(0) && !action.start().isInstantiated()) {
          log.debug("select node " + n.getName() + " for start");
          return action.start();
        }
      }
    }
    return null;
  }
  /**
   * Make a new heuristic. By default, the heuristic doesn't touch the scheduling constraints.
   *
   * @param solver the solver to use to extract the assignment variables
   * @param nodes the nodes to consider
   */
  public EmptyNodeVarSelector(ReconfigurationProblem myPb, ManagedElementSet<Node> myNodes) {
    super(myPb);
    log = Logger.getLogger(this.getClass().getName());
    pb = myPb;
    nodes = myNodes;

    // first criteria: select first the servers that are energy inefficient to switch them off
    F4GNodeComparator cmp =
        new F4GNodeComparator(
            false,
            F4GResourcePicker.NodeRc.powerIdle,
            (Configuration) myPb.getSourceConfiguration());

    Collections.sort(nodes, cmp);
  }