public boolean evaluateConfirmationExpression(
      UserType user,
      ShadowType shadow,
      ExpressionType expressionType,
      Task task,
      OperationResult result)
      throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
    Validate.notNull(user, "User must not be null.");
    Validate.notNull(shadow, "Resource object shadow must not be null.");
    Validate.notNull(expressionType, "Expression must not be null.");
    Validate.notNull(result, "Operation result must not be null.");

    ResourceType resource = resolveResource(shadow, result);
    ExpressionVariables variables = getDefaultXPathVariables(user, shadow, resource);
    String shortDesc = "confirmation expression for " + resource.asPrismObject();

    PrismPropertyDefinition<Boolean> outputDefinition =
        new PrismPropertyDefinition<>(
            ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_BOOLEAN, prismContext);
    Expression<PrismPropertyValue<Boolean>, PrismPropertyDefinition<Boolean>> expression =
        expressionFactory.makeExpression(expressionType, outputDefinition, shortDesc, task, result);

    ExpressionEvaluationContext params =
        new ExpressionEvaluationContext(null, variables, shortDesc, task, result);
    PrismValueDeltaSetTriple<PrismPropertyValue<Boolean>> outputTriple =
        ModelExpressionThreadLocalHolder.evaluateExpressionInContext(
            expression, params, task, result);
    Collection<PrismPropertyValue<Boolean>> nonNegativeValues = outputTriple.getNonNegativeValues();
    if (nonNegativeValues == null || nonNegativeValues.isEmpty()) {
      throw new ExpressionEvaluationException(
          "Expression returned no value (" + nonNegativeValues.size() + ") in " + shortDesc);
    }
    if (nonNegativeValues.size() > 1) {
      throw new ExpressionEvaluationException(
          "Expression returned more than one value ("
              + nonNegativeValues.size()
              + ") in "
              + shortDesc);
    }
    PrismPropertyValue<Boolean> resultpval = nonNegativeValues.iterator().next();
    if (resultpval == null) {
      throw new ExpressionEvaluationException(
          "Expression returned no value (" + nonNegativeValues.size() + ") in " + shortDesc);
    }
    Boolean resultVal = resultpval.getValue();
    if (resultVal == null) {
      throw new ExpressionEvaluationException(
          "Expression returned no value (" + nonNegativeValues.size() + ") in " + shortDesc);
    }
    return resultVal;
  }
  public String evaluateExpression(
      ShadowType shadow,
      ExpressionType expressionType,
      String shortDesc,
      Task task,
      OperationResult result)
      throws ExpressionEvaluationException, ObjectNotFoundException, SchemaException {
    Validate.notNull(shadow, "Resource object shadow must not be null.");
    Validate.notNull(expressionType, "Expression must not be null.");
    Validate.notNull(result, "Operation result must not be null.");

    ResourceType resource = resolveResource(shadow, result);

    ExpressionVariables variables = getDefaultXPathVariables(null, shadow, resource);

    PrismPropertyDefinition<String> outputDefinition =
        new PrismPropertyDefinition<>(
            ExpressionConstants.OUTPUT_ELMENT_NAME, DOMUtil.XSD_STRING, prismContext);
    Expression<PrismPropertyValue<String>, PrismPropertyDefinition<String>> expression =
        expressionFactory.makeExpression(expressionType, outputDefinition, shortDesc, task, result);

    ExpressionEvaluationContext params =
        new ExpressionEvaluationContext(null, variables, shortDesc, task, result);
    PrismValueDeltaSetTriple<PrismPropertyValue<String>> outputTriple =
        ModelExpressionThreadLocalHolder.evaluateExpressionInContext(
            expression, params, task, result);
    if (outputTriple == null) {
      return null;
    }
    Collection<PrismPropertyValue<String>> nonNegativeValues = outputTriple.getNonNegativeValues();
    if (nonNegativeValues == null || nonNegativeValues.isEmpty()) {
      return null;
    }
    if (nonNegativeValues.size() > 1) {
      throw new ExpressionEvaluationException(
          "Expression returned more than one value ("
              + nonNegativeValues.size()
              + ") in "
              + shortDesc);
    }
    return nonNegativeValues.iterator().next().getValue();
  }