private void convertFunction(ExprFunction2 expr) {
    logger.debug("convertFunction " + expr.toString());

    if (expr instanceof E_LogicalOr) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(e1.or(e2));
    } else if (expr instanceof E_LessThan) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new LessThan(e1, e2));
    } else if (expr instanceof E_LessThanOrEqual) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new LessThanOrEqual(e1, e2));
    } else if (expr instanceof E_GreaterThan) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new GreaterThan(e1, e2));
    } else if (expr instanceof E_GreaterThanOrEqual) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new GreaterThanOrEqual(e1, e2));
    } else if (expr instanceof E_Add) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new Add(e1, e2));
    } else if (expr instanceof E_Subtract) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new Subtract(e1, e2));
    } else if (expr instanceof E_Multiply) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new Multiply(e1, e2));
    } else if (expr instanceof E_Divide) {
      expr.getArg1().visit(this);
      expr.getArg2().visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();
      expression.push(new Divide(e1, e2));
    } else if (expr instanceof E_Equals) {
      convertEquals((E_Equals) expr);
    } else if (expr instanceof E_NotEquals) {
      convertNotEquals((E_NotEquals) expr);
    } else if (expr instanceof E_LangMatches) {
      convertLangMatches((E_LangMatches) expr);
    } else if (expr instanceof E_SameTerm) {
      convertSameTerm((E_SameTerm) expr);
    } else if (extensionSupports(expr)) {
      expr.getArg(1).visit(this);
      expr.getArg(2).visit(this);
      Expression e2 = expression.pop();
      Expression e1 = expression.pop();

      List<Expression> args = new ArrayList<Expression>(2);

      args.add(e1);
      args.add(e2);

      extensionConvert(expr, args);
    } else {
      conversionFailed(expr);
    }
  }