@SuppressWarnings("Unchecked")
  public static Object checkImmutable(Class<?> clazz, String fieldName, Object field) {
    Immutable immutable = (Immutable) clazz.getAnnotation(MY_CLASS);
    List<Class> knownImmutableClasses = new ArrayList<Class>();
    if (immutable != null && immutable.knownImmutableClasses().length > 0) {
      knownImmutableClasses = Arrays.asList(immutable.knownImmutableClasses());
    }

    if (field == null
        || field instanceof Enum
        || inImmutableList(field.getClass().getName())
        || knownImmutableClasses.contains(field.getClass())) return field;
    if (field instanceof Collection) return DefaultGroovyMethods.asImmutable((Collection) field);
    if (field.getClass().getAnnotation(MY_CLASS) != null) return field;
    final String typeName = field.getClass().getName();
    throw new RuntimeException(
        createErrorMessage(clazz.getName(), fieldName, typeName, "constructing"));
  }
 private static void addPhaseOperationsForGlobalTransforms(
     CompilationUnit compilationUnit, Map<String, URL> transformNames, boolean isFirstScan) {
   GroovyClassLoader transformLoader = compilationUnit.getTransformLoader();
   for (Map.Entry<String, URL> entry : transformNames.entrySet()) {
     try {
       Class gTransClass = transformLoader.loadClass(entry.getKey(), false, true, false);
       // no inspection unchecked
       GroovyASTTransformation transformAnnotation =
           (GroovyASTTransformation) gTransClass.getAnnotation(GroovyASTTransformation.class);
       if (transformAnnotation == null) {
         compilationUnit
             .getErrorCollector()
             .addWarning(
                 new WarningMessage(
                     WarningMessage.POSSIBLE_ERRORS,
                     "Transform Class "
                         + entry.getKey()
                         + " is specified as a global transform in "
                         + entry.getValue().toExternalForm()
                         + " but it is not annotated by "
                         + GroovyASTTransformation.class.getName()
                         + " the global transform associated with it may fail and cause the compilation to fail.",
                     null,
                     null));
         continue;
       }
       if (ASTTransformation.class.isAssignableFrom(gTransClass)) {
         final ASTTransformation instance = (ASTTransformation) gTransClass.newInstance();
         if (instance instanceof CompilationUnitAware) {
           ((CompilationUnitAware) instance).setCompilationUnit(compilationUnit);
         }
         CompilationUnit.SourceUnitOperation suOp =
             new CompilationUnit.SourceUnitOperation() {
               public void call(SourceUnit source) throws CompilationFailedException {
                 instance.visit(new ASTNode[] {source.getAST()}, source);
               }
             };
         if (isFirstScan) {
           compilationUnit.addPhaseOperation(suOp, transformAnnotation.phase().getPhaseNumber());
         } else {
           compilationUnit.addNewPhaseOperation(
               suOp, transformAnnotation.phase().getPhaseNumber());
         }
       } else {
         compilationUnit
             .getErrorCollector()
             .addError(
                 new SimpleMessage(
                     "Transform Class "
                         + entry.getKey()
                         + " specified at "
                         + entry.getValue().toExternalForm()
                         + " is not an ASTTransformation.",
                     null));
       }
     } catch (Exception e) {
       compilationUnit
           .getErrorCollector()
           .addError(
               new SimpleMessage(
                   "Could not instantiate global transform class "
                       + entry.getKey()
                       + " specified at "
                       + entry.getValue().toExternalForm()
                       + "  because of exception "
                       + e.toString(),
                   null));
     }
   }
 }