private int augmentPath_BFS(int root) {
   in.clear();
   int indexFirst = 0, indexLast = 0;
   fifo[indexLast++] = root;
   in.set(root); // TODO CORRECTION JG 15/11/12 to test on minizinc instance
   int x, y;
   ISet succs;
   while (indexFirst != indexLast) {
     x = fifo[indexFirst++];
     succs = digraph.getSuccessorsOf(x);
     for (y = succs.getFirstElement(); y >= 0; y = succs.getNextElement()) {
       if (!in.get(y)) {
         father[y] = x;
         fifo[indexLast++] = y;
         in.set(y);
         if (flow[y] < this.ub[y]) {
           if (y < n) {
             throw new UnsupportedOperationException();
           }
           return y;
         }
       }
     }
   }
   return -1;
 }
 private void buildDigraph() throws ContradictionException {
   digraph.desactivateNode(n2);
   for (int i = 0; i < n2; i++) {
     flow[i] = 0;
     digraph.getSuccessorsOf(i).clear();
     digraph.getPredecessorsOf(i).clear();
   }
   int j, k, ub;
   IntVar v;
   for (int i = 0; i < n; i++) {
     v = vars[i];
     ub = v.getUB();
     if (v.instantiated()) {
       j = map.get(v.getValue());
       if (flow[j] < this.ub[j]) {
         digraph.addArc(j, i);
         flow[i]++;
         flow[j]++;
       } else {
         contradiction(v, "");
       }
     } else {
       for (k = v.getLB(); k <= ub; k = v.nextValue(k)) {
         j = map.get(k);
         digraph.addArc(i, j);
       }
     }
   }
 }
 private void filter() throws ContradictionException {
   buildSCC();
   int j, ub;
   IntVar v;
   for (int i = 0; i < n; i++) {
     v = vars[i];
     ub = v.getUB();
     if (v.getLB() != ub) { // i.e. v is not instantiated
       for (int k = v.getLB(); k <= ub; k = v.nextValue(k)) {
         j = map.get(k);
         if (nodeSCC[i] != nodeSCC[j]) {
           if (digraph.arcExists(j, i)) {
             v.instantiateTo(k, aCause);
             ISet nei = digraph.getSuccessorsOf(i);
             for (int s = nei.getFirstElement(); s >= 0; s = nei.getNextElement()) {
               digraph.removeArc(i, s);
             }
           } else {
             v.removeValue(k, aCause);
             digraph.removeArc(i, j);
           }
         }
       }
     }
   }
   int nb = boundedVariables.size();
   for (int i = 0; i < nb; i++) {
     v = vars[boundedVariables.get(i)];
     ub = v.getUB();
     for (int k = v.getLB(); k <= ub; k++) {
       j = map.get(k);
       if (!(digraph.arcExists(i, j) || digraph.arcExists(j, i))) {
         v.removeValue(k, aCause);
       }
     }
     int lb = v.getLB();
     for (int k = v.getUB(); k >= lb; k--) {
       j = map.get(k);
       if (!(digraph.arcExists(i, j) || digraph.arcExists(j, i))) {
         v.removeValue(k, aCause);
       }
     }
   }
   // filter cardinality variables
   int idx;
   ISet nei;
   for (int i = 0; i < values.length; i++) {
     idx = map.get(values[i]);
     nei = digraph.getSuccessorsOf(idx);
     ub = nei.getSize() + digraph.getPredecessorsOf(idx).getSize();
     cards[i].updateUpperBound(ub, aCause);
   }
   for (int i = 0; i < values.length; i++) {
     idx = map.get(values[i]);
     int size = digraph.getSuccessorsOf(idx).getSize();
     ub = cards[i].getUB();
     while (size < ub && canUseValue(idx)) {
       size++;
     }
     cards[i].updateUpperBound(size, aCause);
   }
   for (int i = 0; i < values.length; i++) {
     idx = map.get(values[i]);
     while (canUnuseValue(idx)) {}
     cards[i].updateLowerBound(digraph.getSuccessorsOf(idx).getSize(), aCause);
   }
 }