private Statement rewriteCondition(Expression expr, Expression message, boolean explicit) {
    boolean optOut = isOptOutExpression(expr);
    if (optOut) {
      expr = removeOptOutPrefix(expr);
      if (!explicit) {
        return new ExpressionStatement(expr);
      }
    }
    if (isSpecialCollectionCondition(expr)) { // todo check if we can better integrate it
      expr = transformSpecialCollectionCondition(expr);
    }
    // method conditions with spread operator are not lifted because MOP doesn't support spreading
    if (expr instanceof MethodCallExpression && !((MethodCallExpression) expr).isSpreadSafe()) {
      MethodCallExpression methodCallExpression = (MethodCallExpression)expr;
      if (checkIsConditionMethodCall(methodCallExpression)) {
        return surroundSpecialTryCatch(expr);
      }
      return rewriteMethodCondition(methodCallExpression, message, explicit, optOut);
    }

    if (expr instanceof StaticMethodCallExpression)
      return rewriteStaticMethodCondition((StaticMethodCallExpression) expr, message, explicit, optOut);

    return rewriteOtherCondition(expr, message, optOut);
  }
Rewrites explicit ("assert x > 3") and implicit ("x > 3") condition
statements. Replacing the original statement with the rewritten one is up
to clients.

@author Peter Niederwieser
spock-core/src/main/java/org/spockframework/compiler/ConditionRewriter.java