/**
   * Equality is by value.
   *
   * @param object The ConstraintIs object to compare to
   * @return <code>true</code> if object is the same as this.
   */
  public boolean equals(Object object) {
    if (object == null) return false;

    if (object == this) return true;

    // Check that the given object is the correct class
    if (!object.getClass().equals(this.getClass())) return false;

    // Check each element.
    ConstraintAssignment tmpConstraint = (ConstraintAssignment) object;

    if (!context.equals(tmpConstraint.context) || var.equals(tmpConstraint.var)) return false;

    // fudge the value comparison
    boolean exprEq = false;
    Object v1 = null;
    Object v2 = null;
    try {
      v1 = expr.getValue();
      try {
        v2 = tmpConstraint.expr.getValue();
        exprEq = v1.equals(v2);
      } catch (QueryException e2) {
      }
    } catch (QueryException e) {
      try {
        v2 = tmpConstraint.expr.getValue();
      } catch (QueryException e2) {
        exprEq = true;
      }
    }

    return exprEq;
  }
 /**
  * Get all constraints which are variables. This method now uses the fourth element of the triple.
  *
  * @return A set containing all variable constraints.
  */
 public Set<Variable> getVariables() {
   if (variables == null) {
     Set<Variable> v = new HashSet<Variable>(context.getVariables());
     v.add(var);
     variables = Collections.unmodifiableSet(v);
   }
   return variables;
 }
 /**
  * Calculate a semi-unique integer for this object
  *
  * @return a semi-unique integer for this object
  */
 public int hashCode() {
   return context.hashCode() + var.hashCode() + expr.hashCode();
 }