private void createValidateMethod() {
    Validation.Mode mode =
        getEnumMemberValue(
            getAnnotation(annotatedClass, VALIDATION_ANNOTATION),
            "mode",
            Validation.Mode.class,
            Validation.Mode.AUTOMATIC);

    annotatedClass.addField(
        "$manualValidation",
        ACC_PRIVATE,
        ClassHelper.Boolean_TYPE,
        new ConstantExpression(mode == Validation.Mode.MANUAL));
    MethodBuilder.createPublicMethod("manualValidation")
        .param(Boolean_TYPE, "validation")
        .assignS(varX("$manualValidation"), varX("validation"))
        .addTo(annotatedClass);

    MethodBuilder methodBuilder = MethodBuilder.createPublicMethod(VALIDATE_METHOD);

    if (ASTHelper.isDSLObject(annotatedClass.getSuperClass())) {
      methodBuilder.statement(callSuperX(VALIDATE_METHOD));
    }

    BlockStatement block = new BlockStatement();
    validateFields(block);
    validateCustomMethods(block);

    TryCatchStatement tryCatchStatement = new TryCatchStatement(block, EmptyStatement.INSTANCE);
    tryCatchStatement.addCatch(
        new CatchStatement(
            param(ASSERTION_ERROR_TYPE, "e"),
            new ThrowStatement(
                ctorX(VALIDATION_EXCEPTION_TYPE, args(propX(varX("e"), "message"), varX("e"))))));
    tryCatchStatement.addCatch(
        new CatchStatement(
            param(EXCEPTION_TYPE, "e"),
            new ThrowStatement(
                ctorX(VALIDATION_EXCEPTION_TYPE, args(propX(varX("e"), "message"), varX("e"))))));

    methodBuilder.statement(tryCatchStatement).addTo(annotatedClass);
  }