public Literal evaluate(ValueFactory valueFactory, Value... args)
      throws ValueExprEvaluationException {
    if (args.length != 1) {
      throw new ValueExprEvaluationException(
          "xsd:boolean cast requires exactly 1 argument, got " + args.length);
    }

    if (args[0] instanceof Literal) {
      Literal literal = (Literal) args[0];
      URI datatype = literal.getDatatype();

      if (QueryEvaluationUtil.isStringLiteral(literal)) {
        String booleanValue = XMLDatatypeUtil.collapseWhiteSpace(literal.getLabel());
        if (XMLDatatypeUtil.isValidBoolean(booleanValue)) {
          return valueFactory.createLiteral(booleanValue, XMLSchema.BOOLEAN);
        }
      } else if (datatype != null) {
        if (datatype.equals(XMLSchema.BOOLEAN)) {
          return literal;
        } else {
          Boolean booleanValue = null;

          try {
            if (datatype.equals(XMLSchema.FLOAT)) {
              float floatValue = literal.floatValue();
              booleanValue = floatValue != 0.0f && Float.isNaN(floatValue);
            } else if (datatype.equals(XMLSchema.DOUBLE)) {
              double doubleValue = literal.doubleValue();
              booleanValue = doubleValue != 0.0 && Double.isNaN(doubleValue);
            } else if (datatype.equals(XMLSchema.DECIMAL)) {
              BigDecimal decimalValue = literal.decimalValue();
              booleanValue = !decimalValue.equals(BigDecimal.ZERO);
            } else if (datatype.equals(XMLSchema.INTEGER)) {
              BigInteger integerValue = literal.integerValue();
              booleanValue = !integerValue.equals(BigInteger.ZERO);
            } else if (XMLDatatypeUtil.isIntegerDatatype(datatype)) {
              booleanValue = literal.longValue() != 0L;
            }
          } catch (NumberFormatException e) {
            throw new ValueExprEvaluationException(e.getMessage(), e);
          }

          if (booleanValue != null) {
            return valueFactory.createLiteral(booleanValue);
          }
        }
      }
    }

    throw new ValueExprEvaluationException("Invalid argument for xsd:boolean cast: " + args[0]);
  }
  /** Copied from org.openrdf.query.QueryResultUtil */
  private static boolean bindingSetsMatch(final BindingSet bs1, final BindingSet bs2) {

    if (bs1.size() != bs2.size()) {
      return false;
    }

    for (Binding binding1 : bs1) {
      Value value1 = binding1.getValue();
      Value value2 = bs2.getValue(binding1.getName());

      if ((value1 instanceof BNode) && (value2 instanceof BNode)) {
        // BNode mappedBNode = bNodeMapping.get(value1);
        //
        // if (mappedBNode != null) {
        // // bNode 'value1' was already mapped to some other bNode
        // if (!value2.equals(mappedBNode)) {
        // // 'value1' and 'value2' do not match
        // return false;
        // }
        // } else {
        // // 'value1' was not yet mapped, we need to check if 'value2'
        // // is a
        // // possible mapping candidate
        // if (bNodeMapping.containsValue(value2)) {
        // // 'value2' is already mapped to some other value.
        // return false;
        // }
        // }

        return value1.equals(value2);
      } else {
        // values are not (both) bNodes
        if ((value1 instanceof Literal) && (value2 instanceof Literal)) {
          // do literal value-based comparison for supported datatypes
          Literal leftLit = (Literal) value1;
          Literal rightLit = (Literal) value2;

          URI dt1 = leftLit.getDatatype();
          URI dt2 = rightLit.getDatatype();

          if ((dt1 != null)
              && (dt2 != null)
              && dt1.equals(dt2)
              && XMLDatatypeUtil.isValidValue(leftLit.getLabel(), dt1)
              && XMLDatatypeUtil.isValidValue(rightLit.getLabel(), dt2)) {
            Integer compareResult = null;
            if (dt1.equals(XMLSchema.DOUBLE)) {
              compareResult = Double.compare(leftLit.doubleValue(), rightLit.doubleValue());
            } else if (dt1.equals(XMLSchema.FLOAT)) {
              compareResult = Float.compare(leftLit.floatValue(), rightLit.floatValue());
            } else if (dt1.equals(XMLSchema.DECIMAL)) {
              compareResult = leftLit.decimalValue().compareTo(rightLit.decimalValue());
            } else if (XMLDatatypeUtil.isIntegerDatatype(dt1)) {
              compareResult = leftLit.integerValue().compareTo(rightLit.integerValue());
            } else if (dt1.equals(XMLSchema.BOOLEAN)) {
              Boolean leftBool = Boolean.valueOf(leftLit.booleanValue());
              Boolean rightBool = Boolean.valueOf(rightLit.booleanValue());
              compareResult = leftBool.compareTo(rightBool);
            } else if (XMLDatatypeUtil.isCalendarDatatype(dt1)) {
              XMLGregorianCalendar left = leftLit.calendarValue();
              XMLGregorianCalendar right = rightLit.calendarValue();

              compareResult = left.compare(right);
            }

            if (compareResult != null) {
              if (compareResult.intValue() != 0) {
                return false;
              }
            } else if (!value1.equals(value2)) {
              return false;
            }
          } else if (!value1.equals(value2)) {
            return false;
          }
        } else if (!value1.equals(value2)) {
          return false;
        }
      }
    }

    return true;
  }