public boolean leftChild(PrimitiveConstraint choice, boolean status) {

    boolean returnCode = true;

    if (exitChildListeners != null) {
      boolean code = false;
      for (int i = 0; i < exitChildListeners.length; i++)
        code |= exitChildListeners[i].leftChild(choice, status);
      returnCode = code;
    }

    currentSearchNode = searchStack.pop();
    //		SearchNode previousSearchNode = currentSearchNode;

    if (!status && returnCode) {

      currentSearchNode = new SearchNode();
      // currentSearchNode.v = var;

      //			if (previousSearchNode.dom instanceof JaCoP.core.IntDomain)
      //				currentSearchNode.dom = ((IntDomain)previousSearchNode.dom).subtract( value );
      //			else if (previousSearchNode.dom instanceof JaCoP.set.core.SetDomain)
      //				currentSearchNode.dom = ((SetDomain)previousSearchNode.dom).subtract( value, value );

      // currentSearchNode.val = value;
      currentSearchNode.id = searchNodeId++;
      currentSearchNode.equal = false;
      currentSearchNode.c = choice;
      currentSearchNode.previous = searchStack.peek().id;

      searchStack.push(currentSearchNode);
    }

    return returnCode;
  }
  public int getChoiceValue() {

    selectedValue = select.getChoiceValue();
    currentSearchNode.val = selectedValue;
    currentSearchNode.id = searchNodeId++;
    currentSearchNode.previous = searchStack.peek().id;

    searchStack.push(currentSearchNode);

    return selectedValue;
  }
  /**
   * It creates a CPviz trace generator around proper select choice point object.
   *
   * @param select it specifies how the select choice points are being generated.
   * @param vars it specifies variables which are being traced.
   * @param treeFilename it specifies the file name for search tree trace (default tree.xml).
   * @param visFilename it specifies the file name for variable trace (default vis.xml).
   */
  private TraceGenerator(
      SelectChoicePoint<T> select, Var[] vars, String treeFilename, String visFilename) {

    this.select = select;
    this.treeFilename = treeFilename;
    this.visFilename = visFilename;

    SearchNode rootNode = new SearchNode();
    rootNode.id = 0;
    searchStack.push(rootNode);

    // 		for (Var v : vars) {
    for (int i = 0; i < vars.length; i++) {
      tracedVar.add(vars[i]);
      varIndex.put(vars[i], i);
    }

    prepareTreeHeader();
    prepareVizHeader();
  }
  public PrimitiveConstraint getChoiceConstraint(int index) {

    PrimitiveConstraint c = select.getChoiceConstraint(index);

    if (c == null) {

      generateSuccessNode(currentSearchNode.id);
      generateVisualizationNode(currentSearchNode.id, true);

    } else {

      currentSearchNode = new SearchNode();
      currentSearchNode.c = c;
      currentSearchNode.id = searchNodeId++;
      currentSearchNode.previous = searchStack.peek().id;

      searchStack.push(currentSearchNode);
    }

    return c;
  }
  public boolean leftChild(T var, int value, boolean status) {

    boolean returnCode = true;

    if (exitChildListeners != null) {
      boolean code = false;
      for (int i = 0; i < exitChildListeners.length; i++)
        code |= exitChildListeners[i].leftChild(var, value, status);
      returnCode = code;
    }

    currentSearchNode = searchStack.pop();
    SearchNode previousSearchNode = currentSearchNode;

    if (!status && returnCode) {

      currentSearchNode = new SearchNode();
      currentSearchNode.v = var;

      if (previousSearchNode.dom
          instanceof uk.ac.stir.cs.homer.homerPolicyServer.overlap.JaCoP.core.IntDomain)
        currentSearchNode.dom = ((IntDomain) previousSearchNode.dom).subtract(value);
      else if (previousSearchNode.dom
          instanceof uk.ac.stir.cs.homer.homerPolicyServer.overlap.JaCoP.set.core.SetDomain)
        currentSearchNode.dom = ((SetDomain) previousSearchNode.dom).subtract(value, value);

      currentSearchNode.val = value;
      currentSearchNode.id = searchNodeId++;
      currentSearchNode.equal = false;
      currentSearchNode.previous = searchStack.peek().id;

      searchStack.push(currentSearchNode);
    }

    return returnCode;
  }