You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2017/12/20 00:56:42 UTC

[45/49] groovy git commit: Move source files to proper packages

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/grape/GrabAnnotationTransformation.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/grape/GrabAnnotationTransformation.java b/src/main/groovy/grape/GrabAnnotationTransformation.java
deleted file mode 100644
index dd55ff9..0000000
--- a/src/main/groovy/grape/GrabAnnotationTransformation.java
+++ /dev/null
@@ -1,639 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.grape;
-
-import groovy.lang.Grab;
-import groovy.lang.GrabConfig;
-import groovy.lang.GrabExclude;
-import groovy.lang.GrabResolver;
-import groovy.lang.Grapes;
-import groovy.transform.CompilationUnitAware;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ImportNode;
-import org.codehaus.groovy.ast.ModuleNode;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.codehaus.groovy.ast.expr.MapExpression;
-import org.codehaus.groovy.ast.expr.StaticMethodCallExpression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.io.StringReaderSource;
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.tools.GrapeUtil;
-import org.codehaus.groovy.transform.ASTTransformation;
-import org.codehaus.groovy.transform.ASTTransformationVisitor;
-import org.codehaus.groovy.transform.AbstractASTTransformation;
-import org.codehaus.groovy.transform.GroovyASTTransformation;
-
-import java.io.File;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.callThisX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.callX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.constX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.eqX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ifS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
-import static org.codehaus.groovy.transform.AbstractASTTransformation.getMemberStringValue;
-
-/**
- * Transformation for declarative dependency management.
- */
-@GroovyASTTransformation(phase=CompilePhase.CONVERSION)
-public class GrabAnnotationTransformation extends ClassCodeVisitorSupport implements ASTTransformation, CompilationUnitAware {
-    private static final String GRAB_CLASS_NAME = Grab.class.getName();
-    private static final String GRAB_DOT_NAME = GRAB_CLASS_NAME.substring(GRAB_CLASS_NAME.lastIndexOf("."));
-    private static final String GRAB_SHORT_NAME = GRAB_DOT_NAME.substring(1);
-
-    private static final String GRABEXCLUDE_CLASS_NAME = GrabExclude.class.getName();
-    private static final String GRABEXCLUDE_DOT_NAME = dotName(GRABEXCLUDE_CLASS_NAME);
-    private static final String GRABEXCLUDE_SHORT_NAME = shortName(GRABEXCLUDE_DOT_NAME);
-
-    private static final String GRABCONFIG_CLASS_NAME = GrabConfig.class.getName();
-    private static final String GRABCONFIG_DOT_NAME = dotName(GRABCONFIG_CLASS_NAME);
-    private static final String GRABCONFIG_SHORT_NAME = shortName(GRABCONFIG_DOT_NAME);
-
-    private static final String GRAPES_CLASS_NAME = Grapes.class.getName();
-    private static final String GRAPES_DOT_NAME = dotName(GRAPES_CLASS_NAME);
-    private static final String GRAPES_SHORT_NAME = shortName(GRAPES_DOT_NAME);
-
-    private static final String GRABRESOLVER_CLASS_NAME = GrabResolver.class.getName();
-    private static final String GRABRESOLVER_DOT_NAME = dotName(GRABRESOLVER_CLASS_NAME);
-    private static final String GRABRESOLVER_SHORT_NAME = shortName(GRABRESOLVER_DOT_NAME);
-
-    private static final ClassNode THREAD_CLASSNODE = ClassHelper.make(Thread.class);
-    private static final ClassNode SYSTEM_CLASSNODE = ClassHelper.make(System.class);
-
-    private static final List<String> GRABEXCLUDE_REQUIRED = Arrays.asList("group", "module");
-    private static final List<String> GRABRESOLVER_REQUIRED = Arrays.asList("name", "root");
-    private static final List<String> GRAB_REQUIRED = Arrays.asList("group", "module", "version");
-    private static final List<String> GRAB_OPTIONAL = Arrays.asList("classifier", "transitive", "conf", "ext", "type", "changing", "force", "initClass");
-    private static final List<String> GRAB_BOOLEAN = Arrays.asList("transitive", "changing", "force", "initClass");
-    private static final Collection<String> GRAB_ALL = DefaultGroovyMethods.plus(GRAB_REQUIRED, GRAB_OPTIONAL);
-    private static final Pattern IVY_PATTERN = Pattern.compile("([a-zA-Z0-9-/._+=]+)#([a-zA-Z0-9-/._+=]+)(;([a-zA-Z0-9-/.\\(\\)\\[\\]\\{\\}_+=,:@][a-zA-Z0-9-/.\\(\\)\\]\\{\\}_+=,:@]*))?(\\[([a-zA-Z0-9-/._+=,]*)\\])?");
-    private static final Pattern ATTRIBUTES_PATTERN = Pattern.compile("(.*;|^)([a-zA-Z0-9]+)=([a-zA-Z0-9.*\\[\\]\\-\\(\\),]*)$");
-
-    private static final String AUTO_DOWNLOAD_SETTING = Grape.AUTO_DOWNLOAD_SETTING;
-    private static final String DISABLE_CHECKSUMS_SETTING = Grape.DISABLE_CHECKSUMS_SETTING;
-    private static final String SYSTEM_PROPERTIES_SETTING = Grape.SYSTEM_PROPERTIES_SETTING;
-
-    private static String dotName(String className) {
-        return className.substring(className.lastIndexOf("."));
-    }
-
-    private static String shortName(String className) {
-        return className.substring(1);
-    }
-
-    boolean allowShortGrab;
-    Set<String> grabAliases;
-    List<AnnotationNode> grabAnnotations;
-
-    boolean allowShortGrabExcludes;
-    Set<String> grabExcludeAliases;
-    List<AnnotationNode> grabExcludeAnnotations;
-
-    boolean allowShortGrabConfig;
-    Set<String> grabConfigAliases;
-    List<AnnotationNode> grabConfigAnnotations;
-
-    boolean allowShortGrapes;
-    Set<String> grapesAliases;
-    List<AnnotationNode> grapesAnnotations;
-
-    boolean allowShortGrabResolver;
-    Set<String> grabResolverAliases;
-    List<AnnotationNode> grabResolverAnnotations;
-
-    CompilationUnit compilationUnit;
-    SourceUnit sourceUnit;
-    ClassLoader loader;
-    boolean initContextClassLoader;
-    Boolean autoDownload;
-    Boolean disableChecksums;
-    Map<String, String> systemProperties;
-
-    public SourceUnit getSourceUnit() {
-        return sourceUnit;
-    }
-
-    public void setCompilationUnit(final CompilationUnit compilationUnit) {
-        this.compilationUnit = compilationUnit;
-    }
-
-    public void visit(ASTNode[] nodes, SourceUnit source) {
-        sourceUnit = source;
-        loader = null;
-        initContextClassLoader = false;
-
-        ModuleNode mn = (ModuleNode) nodes[0];
-
-        allowShortGrab = true;
-        allowShortGrabExcludes = true;
-        allowShortGrabConfig = true;
-        allowShortGrapes = true;
-        allowShortGrabResolver = true;
-        grabAliases = new HashSet<String>();
-        grabExcludeAliases = new HashSet<String>();
-        grabConfigAliases = new HashSet<String>();
-        grapesAliases = new HashSet<String>();
-        grabResolverAliases = new HashSet<String>();
-        for (ImportNode im : mn.getImports()) {
-            String alias = im.getAlias();
-            String className = im.getClassName();
-            if ((className.endsWith(GRAB_DOT_NAME) && ((alias == null) || (alias.length() == 0)))
-                || (GRAB_CLASS_NAME.equals(alias)))
-            {
-                allowShortGrab = false;
-            } else if (GRAB_CLASS_NAME.equals(className)) {
-                grabAliases.add(im.getAlias());
-            }
-            if ((className.endsWith(GRAPES_DOT_NAME) && ((alias == null) || (alias.length() == 0)))
-                || (GRAPES_CLASS_NAME.equals(alias)))
-            {
-                allowShortGrapes = false;
-            } else if (GRAPES_CLASS_NAME.equals(className)) {
-                grapesAliases.add(im.getAlias());
-            }
-            if ((className.endsWith(GRABRESOLVER_DOT_NAME) && ((alias == null) || (alias.length() == 0)))
-                || (GRABRESOLVER_CLASS_NAME.equals(alias)))
-            {
-                allowShortGrabResolver = false;
-            } else if (GRABRESOLVER_CLASS_NAME.equals(className)) {
-                grabResolverAliases.add(im.getAlias());
-            }
-        }
-
-        List<Map<String,Object>> grabMaps = new ArrayList<Map<String,Object>>();
-        List<Map<String,Object>> grabMapsInit = new ArrayList<Map<String,Object>>();
-        List<Map<String,Object>> grabExcludeMaps = new ArrayList<Map<String,Object>>();
-
-        for (ClassNode classNode : sourceUnit.getAST().getClasses()) {
-            grabAnnotations = new ArrayList<AnnotationNode>();
-            grabExcludeAnnotations = new ArrayList<AnnotationNode>();
-            grabConfigAnnotations = new ArrayList<AnnotationNode>();
-            grapesAnnotations = new ArrayList<AnnotationNode>();
-            grabResolverAnnotations = new ArrayList<AnnotationNode>();
-
-            visitClass(classNode);
-
-            ClassNode grapeClassNode = ClassHelper.make(Grape.class);
-
-            List<Statement> grabResolverInitializers = new ArrayList<Statement>();
-
-            if (!grapesAnnotations.isEmpty()) {
-                for (AnnotationNode node : grapesAnnotations) {
-                    Expression init = node.getMember("initClass");
-                    Expression value = node.getMember("value");
-                    if (value instanceof ListExpression) {
-                        for (Object o : ((ListExpression)value).getExpressions()) {
-                            if (o instanceof ConstantExpression) {
-                                extractGrab(init, (ConstantExpression) o);
-                            }
-                        }
-                    } else if (value instanceof ConstantExpression) {
-                        extractGrab(init, (ConstantExpression) value);
-                    }
-                    // don't worry if it's not a ListExpression, or AnnotationConstant, etc.
-                    // the rest of GroovyC will flag it as a syntax error later, so we don't
-                    // need to raise the error ourselves
-                }
-            }
-
-            if (!grabResolverAnnotations.isEmpty()) {
-                grabResolverAnnotationLoop:
-                for (AnnotationNode node : grabResolverAnnotations) {
-                    Map<String, Object> grabResolverMap = new HashMap<String, Object>();
-                    String sval = getMemberStringValue(node, "value");
-                    if (sval != null && sval.length() > 0) {
-                        for (String s : GRABRESOLVER_REQUIRED) {
-                            String mval = getMemberStringValue(node, s);
-                            if (mval != null && mval.isEmpty()) mval = null;
-                            if (mval != null) {
-                                addError("The attribute \"" + s + "\" conflicts with attribute 'value' in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                                continue grabResolverAnnotationLoop;
-                            }
-                        }
-                        grabResolverMap.put("name", sval);
-                        grabResolverMap.put("root", sval);
-                    } else {
-                        for (String s : GRABRESOLVER_REQUIRED) {
-                            String mval = getMemberStringValue(node, s);
-                            Expression member = node.getMember(s);
-                            if (member == null || (mval != null && mval.isEmpty())) {
-                                addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                                continue grabResolverAnnotationLoop;
-                            } else if (mval == null) {
-                                addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant String in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                                continue grabResolverAnnotationLoop;
-                            }
-                            grabResolverMap.put(s, mval);
-                        }
-                    }
-
-                    // If no scheme is specified for the repository root,
-                    // then turn it into a URI relative to that of the source file.
-                    String root = (String) grabResolverMap.get("root");
-                    if (root != null && !root.contains(":")) {
-                        URI sourceURI = null;
-                        // Since we use the data: scheme for StringReaderSources (which are fairly common)
-                        // and those are not hierarchical we can't use them for making an absolute URI.
-                        if (!(getSourceUnit().getSource() instanceof StringReaderSource)) {
-                            // Otherwise let's trust the source to know where it is from.
-                            // And actually InputStreamReaderSource doesn't know what to do and so returns null.
-                            sourceURI = getSourceUnit().getSource().getURI();
-                        }
-                        // If source doesn't know how to get a reference to itself,
-                        // then let's use the current working directory, since the repo can be relative to that.
-                        if (sourceURI == null) {
-                            sourceURI = new File(".").toURI();
-                        }
-                        try {
-                            URI rootURI = sourceURI.resolve(new URI(root));
-                            grabResolverMap.put("root", rootURI.toString());
-                        } catch (URISyntaxException e) {
-                            // We'll be silent here.
-                            // If the URI scheme is unknown or not hierarchical, then we just can't help them and shouldn't cause any trouble either.
-                            // addError("Attribute \"root\" has value '" + root + "' which can't be turned into a valid URI relative to it's source '" + getSourceUnit().getName() + "' @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                        }
-                    }
-
-                    Grape.addResolver(grabResolverMap);
-                    addGrabResolverAsStaticInitIfNeeded(grapeClassNode, node, grabResolverInitializers, grabResolverMap);
-                }
-            }
-
-            if (!grabConfigAnnotations.isEmpty()) {
-                for (AnnotationNode node : grabConfigAnnotations) {
-                    checkForClassLoader(node);
-                    checkForInitContextClassLoader(node);
-                    checkForAutoDownload(node);
-                    checkForSystemProperties(node);
-                    checkForDisableChecksums(node);
-                }
-                addInitContextClassLoaderIfNeeded(classNode);
-            }
-
-            if (!grabExcludeAnnotations.isEmpty()) {
-                grabExcludeAnnotationLoop:
-                for (AnnotationNode node : grabExcludeAnnotations) {
-                    Map<String, Object> grabExcludeMap = new HashMap<String, Object>();
-                    checkForConvenienceForm(node, true);
-                    for (String s : GRABEXCLUDE_REQUIRED) {
-                        Expression member = node.getMember(s);
-                        if (member == null) {
-                            addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                            continue grabExcludeAnnotationLoop;
-                        } else if (member != null && !(member instanceof ConstantExpression)) {
-                            addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                            continue grabExcludeAnnotationLoop;
-                        }
-                        grabExcludeMap.put(s, ((ConstantExpression)member).getValue());
-                    }
-                    grabExcludeMaps.add(grabExcludeMap);
-                }
-            }
-
-            if (!grabAnnotations.isEmpty()) {
-                grabAnnotationLoop:
-                for (AnnotationNode node : grabAnnotations) {
-                    Map<String, Object> grabMap = new HashMap<String, Object>();
-                    checkForConvenienceForm(node, false);
-                    for (String s : GRAB_ALL) {
-                        Expression member = node.getMember(s);
-                        String mval = getMemberStringValue(node, s);
-                        if (mval != null && mval.isEmpty()) member = null;
-                        if (member == null && !GRAB_OPTIONAL.contains(s)) {
-                            addError("The missing attribute \"" + s + "\" is required in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                            continue grabAnnotationLoop;
-                        } else if (member != null && !(member instanceof ConstantExpression)) {
-                            addError("Attribute \"" + s + "\" has value " + member.getText() + " but should be an inline constant in @" + node.getClassNode().getNameWithoutPackage() + " annotations", node);
-                            continue grabAnnotationLoop;
-                        }
-                        if (node.getMember(s) != null) {
-                            grabMap.put(s, ((ConstantExpression)member).getValue());
-                        }
-                    }
-                    grabMaps.add(grabMap);
-                    if ((node.getMember("initClass") == null) || (node.getMember("initClass") == ConstantExpression.TRUE)) {
-                        grabMapsInit.add(grabMap);
-                    }
-                }
-                callGrabAsStaticInitIfNeeded(classNode, grapeClassNode, grabMapsInit, grabExcludeMaps);
-            }
-
-            if (!grabResolverInitializers.isEmpty()) {
-                classNode.addStaticInitializerStatements(grabResolverInitializers, true);
-            }
-        }
-
-        if (!grabMaps.isEmpty()) {
-            Map<String, Object> basicArgs = new HashMap<String, Object>();
-            basicArgs.put("classLoader", loader != null ? loader : sourceUnit.getClassLoader());
-            if (!grabExcludeMaps.isEmpty()) basicArgs.put("excludes", grabExcludeMaps);
-            if (autoDownload != null) basicArgs.put(AUTO_DOWNLOAD_SETTING, autoDownload);
-            if (disableChecksums != null) basicArgs.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
-            if (systemProperties != null) basicArgs.put(SYSTEM_PROPERTIES_SETTING, systemProperties);
-
-            try {
-                Grape.grab(basicArgs, grabMaps.toArray(new Map[grabMaps.size()]));
-                // grab may have added more transformations through new URLs added to classpath, so do one more scan
-                if (compilationUnit!=null) {
-                    ASTTransformationVisitor.addGlobalTransformsAfterGrab(compilationUnit.getASTTransformationsContext());
-                }
-            } catch (RuntimeException re) {
-                // Decided against syntax exception since this is not a syntax error.
-                // The down side is we lose line number information for the offending
-                // @Grab annotation.
-                source.addException(re);
-            }
-        }
-    }
-
-    private void callGrabAsStaticInitIfNeeded(ClassNode classNode, ClassNode grapeClassNode, List<Map<String,Object>> grabMapsInit, List<Map<String, Object>> grabExcludeMaps) {
-        List<Statement> grabInitializers = new ArrayList<Statement>();
-        MapExpression basicArgs = new MapExpression();
-        if (autoDownload != null)  {
-            basicArgs.addMapEntryExpression(constX(AUTO_DOWNLOAD_SETTING), constX(autoDownload));
-        }
-
-        if (disableChecksums != null)  {
-            basicArgs.addMapEntryExpression(constX(DISABLE_CHECKSUMS_SETTING), constX(disableChecksums));
-        }
-
-        if (systemProperties != null && !systemProperties.isEmpty()) {
-            BlockStatement block = new BlockStatement();
-            for(Map.Entry e : systemProperties.entrySet()) {
-                block.addStatement(stmt(callX(SYSTEM_CLASSNODE, "setProperty", args(constX(e.getKey()), constX(e.getValue())))));
-            }
-            StaticMethodCallExpression enabled = callX(SYSTEM_CLASSNODE, "getProperty", args(constX("groovy.grape.enable"), constX("true")));
-            grabInitializers.add(ifS(eqX(enabled, constX("true")), block));
-        }
-
-        if (!grabExcludeMaps.isEmpty()) {
-            ListExpression list = new ListExpression();
-            for (Map<String, Object> map : grabExcludeMaps) {
-                Set<Map.Entry<String, Object>> entries = map.entrySet();
-                MapExpression inner = new MapExpression();
-                for (Map.Entry<String, Object> entry : entries) {
-                    inner.addMapEntryExpression(constX(entry.getKey()), constX(entry.getValue()));
-                }
-                list.addExpression(inner);
-            }
-            basicArgs.addMapEntryExpression(constX("excludes"), list);
-        }
-
-        List<Expression> argList = new ArrayList<Expression>();
-        argList.add(basicArgs);
-        if (grabMapsInit.isEmpty()) return;
-        for (Map<String, Object> grabMap : grabMapsInit) {
-            // add Grape.grab(excludeArgs, [group:group, module:module, version:version, classifier:classifier])
-            // or Grape.grab([group:group, module:module, version:version, classifier:classifier])
-            MapExpression dependencyArg = new MapExpression();
-            for (String s : GRAB_REQUIRED) {
-                dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
-            }
-            for (String s : GRAB_OPTIONAL) {
-                if (grabMap.containsKey(s))
-                    dependencyArg.addMapEntryExpression(constX(s), constX(grabMap.get(s)));
-            }
-            argList.add(dependencyArg);
-        }
-        grabInitializers.add(stmt(callX(grapeClassNode, "grab", args(argList))));
-
-        // insert at beginning so we have the classloader set up before the class is called
-        classNode.addStaticInitializerStatements(grabInitializers, true);
-    }
-
-    private static void addGrabResolverAsStaticInitIfNeeded(ClassNode grapeClassNode, AnnotationNode node,
-                                                      List<Statement> grabResolverInitializers, Map<String, Object> grabResolverMap) {
-        if ((node.getMember("initClass") == null)
-            || (node.getMember("initClass") == ConstantExpression.TRUE))
-        {
-            MapExpression resolverArgs = new MapExpression();
-            for (Map.Entry<String, Object> next : grabResolverMap.entrySet()) {
-                resolverArgs.addMapEntryExpression(constX(next.getKey()), constX(next.getValue()));
-            }
-            grabResolverInitializers.add(stmt(callX(grapeClassNode, "addResolver", args(resolverArgs))));
-        }
-    }
-
-    private void addInitContextClassLoaderIfNeeded(ClassNode classNode) {
-        if (initContextClassLoader) {
-            Statement initStatement = stmt(callX(
-                            callX(THREAD_CLASSNODE, "currentThread"),
-                            "setContextClassLoader",
-                            callX(callThisX("getClass"), "getClassLoader")
-                    )
-            );
-            classNode.addObjectInitializerStatements(initStatement);
-        }
-    }
-
-    private void checkForClassLoader(AnnotationNode node) {
-        Object val = node.getMember("systemClassLoader");
-        if (val == null || !(val instanceof ConstantExpression)) return;
-        Object systemClassLoaderObject = ((ConstantExpression)val).getValue();
-        if (!(systemClassLoaderObject instanceof Boolean)) return;
-        Boolean systemClassLoader = (Boolean) systemClassLoaderObject;
-        if (systemClassLoader) loader = ClassLoader.getSystemClassLoader();
-    }
-
-    private void checkForInitContextClassLoader(AnnotationNode node) {
-        Object val = node.getMember("initContextClassLoader");
-        if (val == null || !(val instanceof ConstantExpression)) return;
-        Object initContextClassLoaderObject = ((ConstantExpression)val).getValue();
-        if (!(initContextClassLoaderObject instanceof Boolean)) return;
-        initContextClassLoader = (Boolean) initContextClassLoaderObject;
-    }
-
-    private void checkForAutoDownload(AnnotationNode node) {
-        Object val = node.getMember(AUTO_DOWNLOAD_SETTING);
-        if (val == null || !(val instanceof ConstantExpression)) return;
-        Object autoDownloadValue = ((ConstantExpression)val).getValue();
-        if (!(autoDownloadValue instanceof Boolean)) return;
-        autoDownload = (Boolean) autoDownloadValue;
-    }
-
-    private void checkForDisableChecksums(AnnotationNode node) {
-        Object val = node.getMember(DISABLE_CHECKSUMS_SETTING);
-        if (val == null || !(val instanceof ConstantExpression)) return;
-        Object disableChecksumsValue = ((ConstantExpression)val).getValue();
-        if (!(disableChecksumsValue instanceof Boolean)) return;
-        disableChecksums = (Boolean) disableChecksumsValue;
-    }
-
-    private void checkForSystemProperties(AnnotationNode node) {
-        systemProperties = new HashMap<String, String>();
-        List<String> nameValueList = AbstractASTTransformation.getMemberStringList(node, SYSTEM_PROPERTIES_SETTING);
-        if (nameValueList != null) {
-            for (String nameValue : nameValueList) {
-                int equalsDelim = nameValue.indexOf('=');
-                if (equalsDelim != -1) {
-                    systemProperties.put(nameValue.substring(0, equalsDelim), nameValue.substring(equalsDelim + 1));
-                }
-            }
-        }
-    }
-
-    private static void checkForConvenienceForm(AnnotationNode node, boolean exclude) {
-        Object val = node.getMember("value");
-        if (val == null || !(val instanceof ConstantExpression)) return;
-        Object allParts = ((ConstantExpression)val).getValue();
-        if (!(allParts instanceof String)) return;
-        String allstr = (String) allParts;
-
-        // strip off trailing attributes
-        boolean done = false;
-        while (!done) {
-            Matcher attrs = ATTRIBUTES_PATTERN.matcher(allstr);
-            if (attrs.find()) {
-                String attrName = attrs.group(2);
-                String attrValue = attrs.group(3);
-                if (attrName == null || attrValue == null) continue;
-                boolean isBool = GRAB_BOOLEAN.contains(attrName);
-                ConstantExpression value = constX(isBool ? Boolean.valueOf(attrValue) : attrValue);
-                value.setSourcePosition(node);
-                node.addMember(attrName, value);
-                int lastSemi = allstr.lastIndexOf(';');
-                if (lastSemi == -1) {
-                    allstr = "";
-                    break;
-                }
-                allstr = allstr.substring(0, lastSemi);
-            } else {
-                done = true;
-            }
-        }
-
-        if (allstr.contains("#")) {
-            // see: http://ant.apache.org/ivy/history/latest-milestone/textual.html
-            Matcher m = IVY_PATTERN.matcher(allstr);
-            if (!m.find()) return;
-            if (m.group(1) == null || m.group(2) == null) return;
-            node.addMember("module", constX(m.group(2)));
-            node.addMember("group", constX(m.group(1)));
-            if (m.group(6) != null) node.addMember("conf", constX(m.group(6)));
-            if (m.group(4) != null) node.addMember("version", constX(m.group(4)));
-            else if (!exclude && node.getMember("version") == null) node.addMember("version", constX("*"));
-            node.getMembers().remove("value");
-        } else if (allstr.contains(":")) {
-            // assume gradle syntax
-            // see: http://www.gradle.org/latest/docs/userguide/dependency_management.html#sec:how_to_declare_your_dependencies
-            Map<String, Object> parts = GrapeUtil.getIvyParts(allstr);
-            for (Map.Entry<String, Object> entry : parts.entrySet()) {
-                String key = entry.getKey();
-                String value = entry.getValue().toString();
-                if (!key.equals("version") || !value.equals("*") || !exclude) {
-                    node.addMember(key, constX(value));
-                }
-            }
-            node.getMembers().remove("value");
-        }
-    }
-
-    private void extractGrab(Expression init, ConstantExpression ce) {
-        if (ce.getValue() instanceof AnnotationNode) {
-            AnnotationNode annotation = (AnnotationNode) ce.getValue();
-            if ((init != null) && (annotation.getMember("initClass") != null)) {
-                annotation.setMember("initClass", init);
-            }
-            String name = annotation.getClassNode().getName();
-            if ((GRAB_CLASS_NAME.equals(name))
-                    || (allowShortGrab && GRAB_SHORT_NAME.equals(name))
-                    || (grabAliases.contains(name))) {
-                grabAnnotations.add(annotation);
-            }
-            if ((GRABEXCLUDE_CLASS_NAME.equals(name))
-                    || (allowShortGrabExcludes && GRABEXCLUDE_SHORT_NAME.equals(name))
-                    || (grabExcludeAliases.contains(name))) {
-                grabExcludeAnnotations.add(annotation);
-            }
-            if ((GRABCONFIG_CLASS_NAME.equals(name))
-                    || (allowShortGrabConfig && GRABCONFIG_SHORT_NAME.equals(name))
-                    || (grabConfigAliases.contains(name))) {
-                grabConfigAnnotations.add(annotation);
-            }
-            if ((GRABRESOLVER_CLASS_NAME.equals(name))
-                    || (allowShortGrabResolver && GRABRESOLVER_SHORT_NAME.equals(name))
-                    || (grabResolverAliases.contains(name))) {
-                grabResolverAnnotations.add(annotation);
-            }
-        }
-    }
-
-    /**
-     * Adds the annotation to the internal target list if a match is found.
-     *
-     * @param node the AST node we are processing
-     */
-    public void visitAnnotations(AnnotatedNode node) {
-        super.visitAnnotations(node);
-        for (AnnotationNode an : node.getAnnotations()) {
-            String name = an.getClassNode().getName();
-            if ((GRAB_CLASS_NAME.equals(name))
-                    || (allowShortGrab && GRAB_SHORT_NAME.equals(name))
-                    || (grabAliases.contains(name))) {
-                grabAnnotations.add(an);
-            }
-            if ((GRABEXCLUDE_CLASS_NAME.equals(name))
-                    || (allowShortGrabExcludes && GRABEXCLUDE_SHORT_NAME.equals(name))
-                    || (grabExcludeAliases.contains(name))) {
-                grabExcludeAnnotations.add(an);
-            }
-            if ((GRABCONFIG_CLASS_NAME.equals(name))
-                    || (allowShortGrabConfig && GRABCONFIG_SHORT_NAME.equals(name))
-                    || (grabConfigAliases.contains(name))) {
-                grabConfigAnnotations.add(an);
-            }
-            if ((GRAPES_CLASS_NAME.equals(name))
-                    || (allowShortGrapes && GRAPES_SHORT_NAME.equals(name))
-                    || (grapesAliases.contains(name))) {
-                grapesAnnotations.add(an);
-            }
-            if ((GRABRESOLVER_CLASS_NAME.equals(name))
-                    || (allowShortGrabResolver && GRABRESOLVER_SHORT_NAME.equals(name))
-                    || (grabResolverAliases.contains(name))) {
-                grabResolverAnnotations.add(an);
-            }
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/grape/Grape.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/grape/Grape.java b/src/main/groovy/grape/Grape.java
deleted file mode 100644
index c534ded..0000000
--- a/src/main/groovy/grape/Grape.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.grape;
-
-import java.net.URI;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Facade to GrapeEngine.
- */
-public class Grape {
-
-    public static final String AUTO_DOWNLOAD_SETTING = "autoDownload";
-    public static final String DISABLE_CHECKSUMS_SETTING = "disableChecksums";
-    public static final String SYSTEM_PROPERTIES_SETTING = "systemProperties";
-
-    private static boolean enableGrapes = Boolean.valueOf(System.getProperty("groovy.grape.enable", "true"));
-    private static boolean enableAutoDownload = Boolean.valueOf(System.getProperty("groovy.grape.autoDownload", "true"));
-    private static boolean disableChecksums = Boolean.valueOf(System.getProperty("groovy.grape.disableChecksums", "false"));
-    protected static GrapeEngine instance;
-
-    /**
-     * This is a static access kill-switch.  All of the static shortcut
-     * methods in this class will not work if this property is set to false.
-     * By default it is set to true.
-     */
-    public static boolean getEnableGrapes() {
-        return enableGrapes;
-    }
-
-    /**
-     * This is a static access kill-switch.  All of the static shortcut
-     * methods in this class will not work if this property is set to false.
-     * By default it is set to true.
-     */
-    public static void setEnableGrapes(boolean enableGrapes) {
-        Grape.enableGrapes = enableGrapes;
-    }
-
-    /**
-     * This is a static access auto download enabler.  It will set the
-     * 'autoDownload' value to the passed in arguments map if not already set.
-     * If 'autoDownload' is set the value will not be adjusted.
-     * <p>
-     * This applies to the grab and resolve calls.
-     * <p>
-     * If it is set to false, only previously downloaded grapes
-     * will be used.  This may cause failure in the grape call
-     * if the library has not yet been downloaded
-     * <p>
-     * If it is set to true, then any jars not already downloaded will
-     * automatically be downloaded.  Also, any versions expressed as a range
-     * will be checked for new versions and downloaded (with dependencies)
-     * if found.
-     * <p>
-     * By default it is set to true.
-     */
-    public static boolean getEnableAutoDownload() {
-        return enableAutoDownload;
-    }
-
-    /**
-     * This is a static access auto download enabler.  It will set the
-     * 'autoDownload' value to the passed in arguments map if not already
-     * set.  If 'autoDownload' is set the value will not be adjusted.
-     * <p>
-     * This applies to the grab and resolve calls.
-     * <p>
-     * If it is set to false, only previously downloaded grapes
-     * will be used.  This may cause failure in the grape call
-     * if the library has not yet been downloaded.
-     * <p>
-     * If it is set to true, then any jars not already downloaded will
-     * automatically be downloaded.  Also, any versions expressed as a range
-     * will be checked for new versions and downloaded (with dependencies)
-     * if found. By default it is set to true.
-     */
-    public static void setEnableAutoDownload(boolean enableAutoDownload) {
-        Grape.enableAutoDownload = enableAutoDownload;
-    }
-
-    /**
-     * Global flag to ignore checksums.
-     * By default it is set to false.
-     */
-    public static boolean getDisableChecksums() {
-        return disableChecksums;
-    }
-
-    /**
-     * Set global flag to ignore checksums.
-     * By default it is set to false.
-     */
-    public static void setDisableChecksums(boolean disableChecksums) {
-        Grape.disableChecksums = disableChecksums;
-    }
-
-    public static synchronized GrapeEngine getInstance() {
-        if (instance == null) {
-            try {
-                // by default use GrapeIvy
-                //TODO META-INF/services resolver?
-                instance = (GrapeEngine) Class.forName("groovy.grape.GrapeIvy").newInstance();
-            } catch (InstantiationException e) {
-                //LOGME
-            } catch (IllegalAccessException e) {
-                //LOGME
-            } catch (ClassNotFoundException e) {
-                //LOGME
-            }
-        }
-        return instance;
-    }
-
-    public static void grab(String endorsed) {
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                instance.grab(endorsed);
-            }
-        }
-    }
-
-    public static void grab(Map<String, Object> dependency) {
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                if (!dependency.containsKey(AUTO_DOWNLOAD_SETTING)) {
-                    dependency.put(AUTO_DOWNLOAD_SETTING, enableAutoDownload);
-                }
-                if (!dependency.containsKey(DISABLE_CHECKSUMS_SETTING)) {
-                    dependency.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
-                }
-                instance.grab(dependency);
-            }
-        }
-    }
-
-    public static void grab(Map<String, Object> args, Map... dependencies) {
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                if (!args.containsKey(AUTO_DOWNLOAD_SETTING)) {
-                    args.put(AUTO_DOWNLOAD_SETTING, enableAutoDownload);
-                }
-                if (!args.containsKey(DISABLE_CHECKSUMS_SETTING)) {
-                    args.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
-                }
-                instance.grab(args, dependencies);
-            }
-        }
-    }
-
-    public static Map<String, Map<String, List<String>>> enumerateGrapes() {
-        Map<String, Map<String, List<String>>> grapes = null;
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                grapes = instance.enumerateGrapes();
-            }
-        }
-        if (grapes == null) {
-            return Collections.emptyMap();
-        } else {
-            return grapes;
-        }
-    }
-
-    public static URI[] resolve(Map<String, Object> args, Map... dependencies) {
-        return resolve(args, null, dependencies);
-    }
-    
-    public static URI[] resolve(Map<String, Object> args, List depsInfo, Map... dependencies) {
-        URI[] uris = null;
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                if (!args.containsKey(AUTO_DOWNLOAD_SETTING)) {
-                    args.put(AUTO_DOWNLOAD_SETTING, enableAutoDownload);
-                }
-                if (!args.containsKey(DISABLE_CHECKSUMS_SETTING)) {
-                    args.put(DISABLE_CHECKSUMS_SETTING, disableChecksums);
-                }
-                uris = instance.resolve(args, depsInfo, dependencies);
-            }
-        }
-        if (uris == null) {
-            return new URI[0];
-        } else {
-            return uris;
-        }
-    }
-
-    public static Map[] listDependencies(ClassLoader cl) {
-        Map[] maps = null;
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                maps = instance.listDependencies(cl);
-            }
-        }
-        if (maps == null) {
-            return new Map[0];
-        } else {
-            return maps;
-        }
-
-    }
-    
-    public static void addResolver(Map<String, Object> args) {
-        if (enableGrapes) {
-            GrapeEngine instance = getInstance();
-            if (instance != null) {
-                instance.addResolver(args);
-            }
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/grape/GrapeEngine.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/grape/GrapeEngine.java b/src/main/groovy/grape/GrapeEngine.java
deleted file mode 100644
index 4ce171f..0000000
--- a/src/main/groovy/grape/GrapeEngine.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.grape;
-
-import java.net.URI;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Danno Ferrin
- */
-public interface GrapeEngine {
-
-    Object grab(String endorsedModule);
-
-    Object grab(Map args);
-
-    Object grab(Map args, Map... dependencies);
-
-    Map<String, Map<String, List<String>>> enumerateGrapes();
-
-    URI[] resolve(Map args, Map... dependencies);
-
-    URI[] resolve(Map args, List depsInfo, Map... dependencies);
-
-    Map[] listDependencies(ClassLoader classLoader);
-
-    void addResolver(Map<String, Object> args);
-}
-

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/grape/GrapeIvy.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/grape/GrapeIvy.groovy b/src/main/groovy/grape/GrapeIvy.groovy
deleted file mode 100644
index a2c22a8..0000000
--- a/src/main/groovy/grape/GrapeIvy.groovy
+++ /dev/null
@@ -1,729 +0,0 @@
-/*
- *  Licensed to the Apache Software Foundation (ASF) under one
- *  or more contributor license agreements.  See the NOTICE file
- *  distributed with this work for additional information
- *  regarding copyright ownership.  The ASF licenses this file
- *  to you under the Apache License, Version 2.0 (the
- *  "License"); you may not use this file except in compliance
- *  with the License.  You may obtain a copy of the License at
- *
- *    http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing,
- *  software distributed under the License is distributed on an
- *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- *  KIND, either express or implied.  See the License for the
- *  specific language governing permissions and limitations
- *  under the License.
- */
-package groovy.grape
-
-import org.apache.groovy.plugin.GroovyRunner
-import org.apache.groovy.plugin.GroovyRunnerRegistry
-import org.apache.ivy.Ivy
-import org.apache.ivy.core.cache.ResolutionCacheManager
-import org.apache.ivy.core.event.IvyListener
-import org.apache.ivy.core.event.download.PrepareDownloadEvent
-import org.apache.ivy.core.event.resolve.StartResolveEvent
-import org.apache.ivy.core.module.descriptor.Configuration
-import org.apache.ivy.core.module.descriptor.DefaultDependencyArtifactDescriptor
-import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor
-import org.apache.ivy.core.module.descriptor.DefaultExcludeRule
-import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor
-import org.apache.ivy.core.module.id.ArtifactId
-import org.apache.ivy.core.module.id.ModuleId
-import org.apache.ivy.core.module.id.ModuleRevisionId
-import org.apache.ivy.core.report.ArtifactDownloadReport
-import org.apache.ivy.core.report.ResolveReport
-import org.apache.ivy.core.resolve.ResolveOptions
-import org.apache.ivy.core.settings.IvySettings
-import org.apache.ivy.plugins.matcher.ExactPatternMatcher
-import org.apache.ivy.plugins.matcher.PatternMatcher
-import org.apache.ivy.plugins.resolver.ChainResolver
-import org.apache.ivy.plugins.resolver.IBiblioResolver
-import org.apache.ivy.util.DefaultMessageLogger
-import org.apache.ivy.util.Message
-import org.codehaus.groovy.reflection.CachedClass
-import org.codehaus.groovy.reflection.ClassInfo
-import org.codehaus.groovy.reflection.ReflectionUtils
-import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl
-
-import javax.xml.parsers.DocumentBuilderFactory
-import java.util.jar.JarFile
-import java.util.regex.Pattern
-import java.util.zip.ZipEntry
-import java.util.zip.ZipException
-import java.util.zip.ZipFile
-
-/**
- * @author Danno Ferrin
- * @author Paul King
- * @author Roshan Dawrani (roshandawrani)
- */
-class GrapeIvy implements GrapeEngine {
-
-    static final int DEFAULT_DEPTH = 3
-
-    private static final String METAINF_PREFIX = 'META-INF/services/'
-    private static final String RUNNER_PROVIDER_CONFIG = GroovyRunner.class.getName()
-
-    private final exclusiveGrabArgs = [
-            ['group', 'groupId', 'organisation', 'organization', 'org'],
-            ['module', 'artifactId', 'artifact'],
-            ['version', 'revision', 'rev'],
-            ['conf', 'scope', 'configuration'],
-        ].inject([:], {m, g -> g.each {a -> m[a] = (g - a) as Set};  m})
-
-    boolean enableGrapes
-    Ivy ivyInstance
-    Set<String> resolvedDependencies
-    Set<String> downloadedArtifacts
-    // weak hash map so we don't leak loaders directly
-    Map<ClassLoader, Set<IvyGrabRecord>> loadedDeps = new WeakHashMap<ClassLoader, Set<IvyGrabRecord>>()
-    // set that stores the IvyGrabRecord(s) for all the dependencies in each grab() call
-    Set<IvyGrabRecord> grabRecordsForCurrDependencies = new LinkedHashSet<IvyGrabRecord>()
-    // we keep the settings so that addResolver can add to the resolver chain
-    IvySettings settings
-
-    public GrapeIvy() {
-        // if we are already initialized, quit
-        if (enableGrapes) return
-
-        // start ivy
-        Message.defaultLogger = new DefaultMessageLogger(System.getProperty("ivy.message.logger.level", "-1") as int)
-        settings = new IvySettings()
-
-        // configure settings
-        def grapeConfig = getLocalGrapeConfig()
-        if (!grapeConfig.exists()) {
-            grapeConfig = GrapeIvy.getResource("defaultGrapeConfig.xml")
-        }
-        try {
-            settings.load(grapeConfig) // exploit multi-methods for convenience
-        } catch (java.text.ParseException ex) {
-            def configLocation = grapeConfig instanceof File ? grapeConfig.canonicalPath : grapeConfig.toString()
-            System.err.println "Local Ivy config file '$configLocation' appears corrupt - ignoring it and using default config instead\nError was: " + ex.message
-            grapeConfig = GrapeIvy.getResource("defaultGrapeConfig.xml")
-            settings.load(grapeConfig)
-        }
-
-        // set up the cache dirs
-        settings.defaultCache = getGrapeCacheDir()
-
-        settings.setVariable("ivy.default.configuration.m2compatible", "true")
-        ivyInstance = Ivy.newInstance(settings)
-        org.apache.ivy.core.IvyContext.getContext().setIvy(ivyInstance);
-        resolvedDependencies = []
-        downloadedArtifacts = []
-
-        //TODO add grab to the DGM??
-
-        enableGrapes = true
-    }
-
-    public File getGroovyRoot() {
-        String root = System.getProperty("groovy.root")
-        def groovyRoot
-        if (root == null) {
-            groovyRoot = new File(System.getProperty("user.home"), ".groovy")
-        } else {
-            groovyRoot = new File(root)
-        }
-        try {
-            groovyRoot = groovyRoot.canonicalFile
-        } catch (IOException e) {
-            // skip canonicalization then, it may not exist yet
-        }
-        return groovyRoot
-    }
-
-    public File getLocalGrapeConfig() {
-        String grapeConfig = System.getProperty("grape.config")
-        if(grapeConfig) {
-            return new File(grapeConfig)
-        }
-        return new File(getGrapeDir(), 'grapeConfig.xml')
-    }
-
-    public File getGrapeDir() {
-        String root = System.getProperty("grape.root")
-        if(root == null) {
-            return getGroovyRoot()
-        }
-        File grapeRoot = new File(root)
-        try {
-            grapeRoot = grapeRoot.canonicalFile
-        } catch (IOException e) {
-            // skip canonicalization then, it may not exist yet
-        }
-        return grapeRoot
-    }
-
-    public File getGrapeCacheDir() {
-        File cache =  new File(getGrapeDir(), 'grapes')
-        if (!cache.exists()) {
-            cache.mkdirs()
-        } else if (!cache.isDirectory()) {
-            throw new RuntimeException("The grape cache dir $cache is not a directory")
-        }
-        return cache
-    }
-
-    public def chooseClassLoader(Map args) {
-        def loader = args.classLoader
-        if (!isValidTargetClassLoader(loader)) {
-            loader = (args.refObject?.class
-                        ?:ReflectionUtils.getCallingClass(args.calleeDepth?:1)
-                      )?.classLoader
-            while (loader && !isValidTargetClassLoader(loader)) {
-                loader = loader.parent
-            }
-            //if (!isValidTargetClassLoader(loader)) {
-            //    loader = Thread.currentThread().contextClassLoader
-            //}
-            //if (!isValidTargetClassLoader(loader)) {
-            //    loader = GrapeIvy.class.classLoader
-            //}
-            if (!isValidTargetClassLoader(loader)) {
-                throw new RuntimeException("No suitable ClassLoader found for grab")
-            }
-        }
-        return loader
-    }
-
-    private boolean isValidTargetClassLoader(loader) {
-        return isValidTargetClassLoaderClass(loader?.class)
-    }
-
-    private boolean isValidTargetClassLoaderClass(Class loaderClass) {
-        return (loaderClass != null) &&
-            (
-             (loaderClass.name == 'groovy.lang.GroovyClassLoader') ||
-             (loaderClass.name == 'org.codehaus.groovy.tools.RootLoader') ||
-             isValidTargetClassLoaderClass(loaderClass.superclass)
-            )
-    }
-
-    public IvyGrabRecord createGrabRecord(Map deps) {
-        // parse the actual dependency arguments
-        String module =  deps.module ?: deps.artifactId ?: deps.artifact
-        if (!module) {
-            throw new RuntimeException('grab requires at least a module: or artifactId: or artifact: argument')
-        }
-
-        String groupId = deps.group ?: deps.groupId ?: deps.organisation ?: deps.organization ?: deps.org ?: ''
-        String ext = deps.ext ?: deps.type ?: ''
-        String type = deps.type ?: ''
-
-        //TODO accept ranges and decode them?  except '1.0.0'..<'2.0.0' won't work in groovy
-        String version = deps.version ?: deps.revision ?: deps.rev ?: '*'
-        if ('*' == version) version = 'latest.default'
-
-        ModuleRevisionId mrid = ModuleRevisionId.newInstance(groupId, module, version)
-
-        boolean force      = deps.containsKey('force')      ? deps.force      : true
-        boolean changing   = deps.containsKey('changing')   ? deps.changing   : false
-        boolean transitive = deps.containsKey('transitive') ? deps.transitive : true
-        def conf = deps.conf ?: deps.scope ?: deps.configuration ?: ['default']
-        if (conf instanceof String) {
-            if (conf.startsWith("[") && conf.endsWith("]")) conf = conf[1..-2]
-            conf = conf.split(",").toList()
-        }
-        def classifier = deps.classifier ?: null
-
-        return new IvyGrabRecord(mrid:mrid, conf:conf, changing:changing, transitive:transitive, force:force, classifier:classifier, ext:ext, type:type)
-    }
-
-    public grab(String endorsedModule) {
-        return grab(group:'groovy.endorsed', module:endorsedModule, version:GroovySystem.version)
-    }
-
-    public grab(Map args) {
-        args.calleeDepth = args.calleeDepth?:DEFAULT_DEPTH + 1
-        return grab(args, args)
-    }
-
-    public grab(Map args, Map... dependencies) {
-        ClassLoader loader = null
-        grabRecordsForCurrDependencies.clear()
-
-        try {
-            // identify the target classloader early, so we fail before checking repositories
-            loader = chooseClassLoader(
-                classLoader:args.remove('classLoader'),
-                refObject:args.remove('refObject'),
-                calleeDepth:args.calleeDepth?:DEFAULT_DEPTH,
-            )
-
-            // check for non-fail null.
-            // If we were in fail mode we would have already thrown an exception
-            if (!loader) return
-
-            def uris = resolve(loader, args, dependencies)
-            for (URI uri in uris) {
-                loader.addURL(uri.toURL())
-            }
-            boolean runnerServicesFound = false
-            for (URI uri in uris) {
-                //TODO check artifact type, jar vs library, etc
-                File file = new File(uri)
-                processCategoryMethods(loader, file)
-                Collection<String> services = processMetaInfServices(loader, file)
-                if (!runnerServicesFound) {
-                    runnerServicesFound = services.contains(RUNNER_PROVIDER_CONFIG)
-                }
-            }
-            if (runnerServicesFound) {
-                GroovyRunnerRegistry.getInstance().load(loader)
-            }
-        } catch (Exception e) {
-            // clean-up the state first
-            Set<IvyGrabRecord> grabRecordsForCurrLoader = getLoadedDepsForLoader(loader)
-            grabRecordsForCurrLoader.removeAll(grabRecordsForCurrDependencies)
-            grabRecordsForCurrDependencies.clear()
-
-            if (args.noExceptions) {
-                return e
-            }
-            throw e
-        }
-        return null
-    }
-
-    private processCategoryMethods(ClassLoader loader, File file) {
-        // register extension methods if jar
-        if (file.name.toLowerCase().endsWith(".jar")) {
-            def mcRegistry = GroovySystem.metaClassRegistry
-            if (mcRegistry instanceof MetaClassRegistryImpl) {
-                try {
-                    JarFile jar = new JarFile(file)
-                    def entry = jar.getEntry(MetaClassRegistryImpl.MODULE_META_INF_FILE)
-                    if (entry) {
-                        Properties props = new Properties()
-                        props.load(jar.getInputStream(entry))
-                        Map<CachedClass, List<MetaMethod>> metaMethods = new HashMap<CachedClass, List<MetaMethod>>()
-                        mcRegistry.registerExtensionModuleFromProperties(props, loader, metaMethods)
-                        // add old methods to the map
-                        metaMethods.each { CachedClass c, List<MetaMethod> methods ->
-                            // GROOVY-5543: if a module was loaded using grab, there are chances that subclasses
-                            // have their own ClassInfo, and we must change them as well!
-                            Set<CachedClass> classesToBeUpdated = [c]
-                            ClassInfo.onAllClassInfo { ClassInfo info ->
-                                if (c.theClass.isAssignableFrom(info.cachedClass.theClass)) {
-                                    classesToBeUpdated << info.cachedClass
-                                }
-                            }
-                            classesToBeUpdated*.addNewMopMethods(methods)
-                        }
-                    }
-                }
-                catch(ZipException zipException) {
-                    throw new RuntimeException("Grape could not load jar '$file'", zipException)
-                }
-            }
-        }
-    }
-
-    void processOtherServices(ClassLoader loader, File f) {
-        processMetaInfServices(loader, f) // ignore result
-    }
-
-    /**
-     * Searches the given File for known service provider
-     * configuration files to process.
-     *
-     * @param loader used to locate service provider files
-     * @param f ZipFile in which to search for services
-     * @return a collection of service provider files that were found
-     */
-    private Collection<String> processMetaInfServices(ClassLoader loader, File f) {
-        List<String> services = new ArrayList<>()
-        try {
-            ZipFile zf = new ZipFile(f)
-            String providerConfig = 'org.codehaus.groovy.runtime.SerializedCategoryMethods'
-            ZipEntry serializedCategoryMethods = zf.getEntry(METAINF_PREFIX + providerConfig)
-            if (serializedCategoryMethods != null) {
-                services.add(providerConfig)
-                processSerializedCategoryMethods(zf.getInputStream(serializedCategoryMethods))
-            }
-            // TODO: remove in a future release (replaced by GroovyRunnerRegistry)
-            providerConfig = 'org.codehaus.groovy.plugins.Runners'
-            ZipEntry pluginRunners = zf.getEntry(METAINF_PREFIX + providerConfig)
-            if (pluginRunners != null) {
-                services.add(providerConfig)
-                processRunners(zf.getInputStream(pluginRunners), f.getName(), loader)
-            }
-            // GroovyRunners are loaded per ClassLoader using a ServiceLoader so here
-            // it only needs to be indicated that the service provider file was found
-            if (zf.getEntry(METAINF_PREFIX + RUNNER_PROVIDER_CONFIG) != null) {
-                services.add(RUNNER_PROVIDER_CONFIG)
-            }
-        } catch(ZipException ignore) {
-            // ignore files we can't process, e.g. non-jar/zip artifacts
-            // TODO log a warning
-        }
-        return services
-    }
-
-    void processSerializedCategoryMethods(InputStream is) {
-        is.text.readLines().each {
-            println it.trim() // TODO implement this or delete it
-        }
-    }
-
-    void processRunners(InputStream is, String name, ClassLoader loader) {
-        GroovyRunnerRegistry registry = GroovyRunnerRegistry.getInstance()
-        is.text.readLines()*.trim().findAll{ !it.isEmpty() && it[0] != '#' }.each {
-            try {
-                registry[name] = loader.loadClass(it).newInstance()
-            } catch (Exception ex) {
-                throw new IllegalStateException("Error registering runner class '" + it + "'", ex)
-            }
-        }
-    }
-
-    public ResolveReport getDependencies(Map args, IvyGrabRecord... grabRecords) {
-        ResolutionCacheManager cacheManager = ivyInstance.resolutionCacheManager
-
-        def millis = System.currentTimeMillis()
-        def md = new DefaultModuleDescriptor(ModuleRevisionId
-                .newInstance("caller", "all-caller", "working" + millis.toString()[-2..-1]), "integration", null, true)
-        md.addConfiguration(new Configuration('default'))
-        md.setLastModified(millis)
-
-        addExcludesIfNeeded(args, md)
-
-        for (IvyGrabRecord grabRecord : grabRecords) {
-            def conf = grabRecord.conf ?: ['*']
-            DefaultDependencyDescriptor dd = md.dependencies.find {it.dependencyRevisionId.equals(grabRecord.mrid)}
-            if (dd) {
-                createAndAddDependencyArtifactDescriptor(dd, grabRecord, conf)
-            } else {
-                dd = new DefaultDependencyDescriptor(md, grabRecord.mrid, grabRecord.force,
-                        grabRecord.changing, grabRecord.transitive)
-                conf.each {dd.addDependencyConfiguration('default', it)}
-                createAndAddDependencyArtifactDescriptor(dd, grabRecord, conf)
-                md.addDependency(dd)
-            }
-        }
-
-       // resolve grab and dependencies
-        ResolveOptions resolveOptions = new ResolveOptions()\
-            .setConfs(['default'] as String[])\
-            .setOutputReport(false)\
-            .setValidate(args.containsKey('validate') ? args.validate : false)
-
-        ivyInstance.settings.defaultResolver = args.autoDownload ? 'downloadGrapes' : 'cachedGrapes'
-        if (args.disableChecksums) {
-            ivyInstance.settings.setVariable('ivy.checksums', '')
-        }
-        boolean reportDownloads = System.getProperty('groovy.grape.report.downloads', 'false') == 'true'
-        if (reportDownloads) {
-            ivyInstance.eventManager.addIvyListener([progress:{ ivyEvent -> switch(ivyEvent) {
-                case StartResolveEvent:
-                    ivyEvent.moduleDescriptor.dependencies.each { it ->
-                        def name = it.toString()
-                        if (!resolvedDependencies.contains(name)) {
-                            resolvedDependencies << name
-                            System.err.println "Resolving " + name
-                        }
-                    }
-                    break
-                case PrepareDownloadEvent:
-                    ivyEvent.artifacts.each { it ->
-                        def name = it.toString()
-                        if (!downloadedArtifacts.contains(name)) {
-                            downloadedArtifacts << name
-                            System.err.println "Preparing to download artifact " + name
-                        }
-                    }
-                    break
-            } } ] as IvyListener)
-        }
-
-        ResolveReport report = null
-        int attempt = 8 // max of 8 times
-        while (true) {
-            try {
-                report = ivyInstance.resolve(md, resolveOptions)
-                break
-            } catch(IOException ioe) {
-                if (attempt--) {
-                    if (reportDownloads)
-                        System.err.println "Grab Error: retrying..."
-                    sleep attempt > 4 ? 350 : 1000
-                    continue
-                }
-                throw new RuntimeException("Error grabbing grapes -- $ioe.message")
-            }
-        }
-
-        if (report.hasError()) {
-            throw new RuntimeException("Error grabbing Grapes -- $report.allProblemMessages")
-        }
-        if (report.downloadSize && reportDownloads) {
-            System.err.println "Downloaded ${report.downloadSize >> 10} Kbytes in ${report.downloadTime}ms:\n  ${report.allArtifactsReports*.toString().join('\n  ')}"
-        }
-        md = report.moduleDescriptor
-
-        if (!args.preserveFiles) {
-            cacheManager.getResolvedIvyFileInCache(md.moduleRevisionId).delete()
-            cacheManager.getResolvedIvyPropertiesInCache(md.moduleRevisionId).delete()
-        }
-
-        return report
-    }
-
-    private void createAndAddDependencyArtifactDescriptor(DefaultDependencyDescriptor dd, IvyGrabRecord grabRecord, List<String> conf) {
-        // TODO: find out "unknown" reason and change comment below - also, confirm conf[0] check vs conf.contains('optional')
-        if (conf[0]!="optional" || grabRecord.classifier) {  // for some unknown reason optional dependencies should not have an artifactDescriptor
-            def dad = new DefaultDependencyArtifactDescriptor(dd,
-                    grabRecord.mrid.name, grabRecord.type ?: 'jar', grabRecord.ext ?: 'jar', null, grabRecord.classifier ? [classifier: grabRecord.classifier] : null)
-            conf.each { dad.addConfiguration(it) }
-            dd.addDependencyArtifact('default', dad)
-        }
-    }
-
-    public void uninstallArtifact(String group, String module, String rev) {
-        // TODO consider transitive uninstall as an option
-        Pattern ivyFilePattern = ~/ivy-(.*)\.xml/ //TODO get pattern from ivy conf
-        grapeCacheDir.eachDir { File groupDir ->
-            if (groupDir.name == group) groupDir.eachDir { File moduleDir ->
-                if (moduleDir.name == module) moduleDir.eachFileMatch(ivyFilePattern) { File ivyFile ->
-                    def m = ivyFilePattern.matcher(ivyFile.name)
-                    if (m.matches() && m.group(1) == rev) {
-                        // TODO handle other types? e.g. 'dlls'
-                        def jardir = new File(moduleDir, 'jars')
-                        if (!jardir.exists()) return
-                        def dbf = DocumentBuilderFactory.newInstance()
-                        def db = dbf.newDocumentBuilder()
-                        def root = db.parse(ivyFile).documentElement
-                        def publis = root.getElementsByTagName('publications')
-                        for (int i=0; i<publis.length;i++) {
-                            def artifacts = publis.item(i).getElementsByTagName('artifact')
-                            for (int j=0; j<artifacts.length; j++) {
-                                def artifact = artifacts.item(j)
-                                def attrs = artifact.attributes
-                                def name = attrs.getNamedItem('name').getTextContent() + "-$rev"
-                                def classifier = attrs.getNamedItemNS("m", "classifier")?.getTextContent()
-                                if (classifier) name += "-$classifier"
-                                name += ".${attrs.getNamedItem('ext').getTextContent()}"
-                                def jarfile = new File(jardir, name)
-                                if (jarfile.exists()) {
-                                    println "Deleting ${jarfile.name}"
-                                    jarfile.delete()
-                                }
-                            }
-                        }
-                        ivyFile.delete()
-                    }
-                }
-            }
-        }
-    }
-
-    private addExcludesIfNeeded(Map args, DefaultModuleDescriptor md) {
-        if (!args.containsKey('excludes')) return
-        args.excludes.each{ map ->
-            def excludeRule = new DefaultExcludeRule(new ArtifactId(
-                    new ModuleId(map.group, map.module), PatternMatcher.ANY_EXPRESSION,
-                    PatternMatcher.ANY_EXPRESSION,
-                    PatternMatcher.ANY_EXPRESSION),
-                    ExactPatternMatcher.INSTANCE, null)
-            excludeRule.addConfiguration('default')
-            md.addExcludeRule(excludeRule)
-        }
-    }
-
-    public Map<String, Map<String, List<String>>> enumerateGrapes() {
-        Map<String, Map<String, List<String>>> bunches = [:]
-        Pattern ivyFilePattern = ~/ivy-(.*)\.xml/ //TODO get pattern from ivy conf
-        grapeCacheDir.eachDir {File groupDir ->
-            Map<String, List<String>> grapes = [:]
-            bunches[groupDir.name] = grapes
-            groupDir.eachDir { File moduleDir ->
-                def versions = []
-                moduleDir.eachFileMatch(ivyFilePattern) {File ivyFile ->
-                    def m = ivyFilePattern.matcher(ivyFile.name)
-                    if (m.matches()) versions += m.group(1)
-                }
-                grapes[moduleDir.name] = versions
-            }
-        }
-        return bunches
-    }
-
-    public URI[] resolve(Map args, Map ... dependencies) {
-        resolve(args, null, dependencies)
-    }
-
-    public URI[] resolve(Map args, List depsInfo, Map ... dependencies) {
-        // identify the target classloader early, so we fail before checking repositories
-        def loader = chooseClassLoader(
-                classLoader: args.remove('classLoader'),
-                refObject: args.remove('refObject'),
-                calleeDepth: args.calleeDepth ?: DEFAULT_DEPTH,
-        )
-
-        // check for non-fail null.
-        // If we were in fail mode we would have already thrown an exception
-        if (!loader) return
-
-        resolve(loader, args, depsInfo, dependencies)
-    }
-
-    URI [] resolve(ClassLoader loader, Map args, Map... dependencies) {
-        return resolve(loader, args, null, dependencies)
-    }
-
-    URI [] resolve(ClassLoader loader, Map args, List depsInfo, Map... dependencies) {
-        // check for mutually exclusive arguments
-        Set keys = args.keySet()
-        keys.each {a ->
-            Set badArgs = exclusiveGrabArgs[a]
-            if (badArgs && !badArgs.disjoint(keys)) {
-                throw new RuntimeException("Mutually exclusive arguments passed into grab: ${keys.intersect(badArgs) + a}")
-            }
-        }
-
-        // check the kill switch
-        if (!enableGrapes) { return }
-
-        boolean populateDepsInfo = (depsInfo != null)
-
-        Set<IvyGrabRecord> localDeps = getLoadedDepsForLoader(loader)
-
-        dependencies.each {
-            IvyGrabRecord igr = createGrabRecord(it)
-            grabRecordsForCurrDependencies.add(igr)
-            localDeps.add(igr)
-        }
-        // the call to reverse ensures that the newest additions are in
-        // front causing existing dependencies to come last and thus
-        // claiming higher priority.  Thus when module versions clash we
-        // err on the side of using the class already loaded into the
-        // classloader rather than adding another jar of the same module
-        // with a different version
-        ResolveReport report = null
-        try {
-            report = getDependencies(args, *localDeps.asList().reverse())
-        } catch (Exception e) {
-            // clean-up the state first
-            localDeps.removeAll(grabRecordsForCurrDependencies)
-            grabRecordsForCurrDependencies.clear()
-            throw e
-        }
-
-        List<URI> results = []
-        for (ArtifactDownloadReport adl in report.allArtifactsReports) {
-            //TODO check artifact type, jar vs library, etc
-            if (adl.localFile) {
-                results += adl.localFile.toURI()
-            }
-        }
-
-        if (populateDepsInfo) {
-            def deps = report.dependencies
-            deps.each { depNode ->
-                def id = depNode.id
-                depsInfo << ['group' : id.organisation, 'module' : id.name, 'revision' : id.revision]
-            }
-        }
-
-        return results as URI[]
-    }
-
-    private Set<IvyGrabRecord> getLoadedDepsForLoader(ClassLoader loader) {
-        Set<IvyGrabRecord> localDeps = loadedDeps.get(loader)
-        if (localDeps == null) {
-            // use a linked set to preserve initial insertion order
-            localDeps = new LinkedHashSet<IvyGrabRecord>()
-            loadedDeps.put(loader, localDeps)
-        }
-        return localDeps
-    }
-
-    public Map[] listDependencies (ClassLoader classLoader) {
-        if (loadedDeps.containsKey(classLoader)) {
-            List<Map> results = []
-            loadedDeps[classLoader].each { IvyGrabRecord grabbed ->
-                def dep =  [
-                    group : grabbed.mrid.organisation,
-                    module : grabbed.mrid.name,
-                    version : grabbed.mrid.revision
-                ]
-                if (grabbed.conf != ['default']) {
-                    dep.conf = grabbed.conf
-                }
-                if (grabbed.changing) {
-                    dep.changing = grabbed.changing
-                }
-                if (!grabbed.transitive) {
-                    dep.transitive = grabbed.transitive
-                }
-                if (!grabbed.force) {
-                    dep.force = grabbed.force
-                }
-                if (grabbed.classifier) {
-                    dep.classifier = grabbed.classifier
-                }
-                if (grabbed.ext) {
-                    dep.ext = grabbed.ext
-                }
-                if (grabbed.type) {
-                    dep.type = grabbed.type
-                }
-                results << dep
-            }
-            return results
-        }
-        return null
-    }
-
-    public void addResolver(Map<String, Object> args) {
-        ChainResolver chainResolver = settings.getResolver("downloadGrapes")
-
-        IBiblioResolver resolver = new IBiblioResolver(name: args.name, root:args.root,
-              m2compatible:(args.m2Compatible ?: true), settings:settings)
-
-        chainResolver.add(resolver)
-
-        ivyInstance = Ivy.newInstance(settings)
-        resolvedDependencies = []
-        downloadedArtifacts = []
-    }
-}
-
-class IvyGrabRecord {
-    ModuleRevisionId mrid
-    List<String> conf
-    boolean changing
-    boolean transitive
-    boolean force
-    String classifier
-    String ext
-    String type
-
-    public int hashCode() {
-        return (mrid.hashCode() ^ conf.hashCode()
-            ^ (changing ? 0xaaaaaaaa : 0x55555555)
-            ^ (transitive ? 0xbbbbbbbb : 0x66666666)
-            ^ (force ? 0xcccccccc: 0x77777777)
-            ^ (classifier ? classifier.hashCode() : 0)
-            ^ (ext ? ext.hashCode() : 0)
-            ^ (type ? type.hashCode() : 0))
-    }
-
-    public boolean equals(Object o) {
-        return ((o.class == IvyGrabRecord)
-            && (changing == o.changing)
-            && (transitive == o.transitive)
-            && (force== o.force)
-            && (mrid == o.mrid)
-            && (conf == o.conf)
-            && (classifier == o.classifier)
-            && (ext == o.ext)
-            && (type == o.type))
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/10110145/src/main/groovy/groovy/beans/Bindable.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/groovy/beans/Bindable.java b/src/main/groovy/groovy/beans/Bindable.java
new file mode 100644
index 0000000..e9bd292
--- /dev/null
+++ b/src/main/groovy/groovy/beans/Bindable.java
@@ -0,0 +1,116 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ */
+package groovy.beans;
+
+import org.codehaus.groovy.transform.GroovyASTTransformationClass;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotates a groovy property or a class.
+ *
+ * When annotating a property it indicates that the property should be a
+ * bound property according to the JavaBeans spec, announcing to listeners
+ * that the value has changed.
+ * <p>
+ * When annotating a class it indicates that all groovy properties in that
+ * class should be bound as though each property had the annotation (even
+ * if it already has it explicitly).
+ * <p>
+ * It is a compilation error to place this annotation on a field (that is
+ * not a property, i.e. has scope visibility modifiers).
+ * <p>
+ * If a property with a user defined setter method is annotated the code
+ * block is wrapped with the needed code to fire off the event.
+ * <p>
+ * The following example shows how you can use this annotation on fields
+ * of a class: 
+ * <pre>
+ * class Person {
+ *    &#064;groovy.beans.Bindable
+ *    String firstName
+ *
+ *    &#064;groovy.beans.Bindable
+ *    def zipCode
+ * }
+ * </pre>
+ * The above example will generate code that is similar to the next snippet. 
+ * Notice the difference between a String property and a def/Object property: 
+ * <pre>
+ * public class Person { 
+ *     &#064;groovy.beans.Bindable
+ *     private java.lang.String firstName 
+ *     &#064;groovy.beans.Bindable
+ *     private java.lang.Object zipCode 
+ *     final private java.beans.PropertyChangeSupport this$propertyChangeSupport 
+ * 
+ *     public Person() {
+ *         this$propertyChangeSupport = new java.beans.PropertyChangeSupport(this)
+ *     }
+ * 
+ *     public void addPropertyChangeListener(java.beans.PropertyChangeListener listener) {
+ *         this$propertyChangeSupport.addPropertyChangeListener(listener)
+ *     }
+ * 
+ *     public void addPropertyChangeListener(java.lang.String name, java.beans.PropertyChangeListener listener) {
+ *         this$propertyChangeSupport.addPropertyChangeListener(name, listener)
+ *     }
+ * 
+ *     public void removePropertyChangeListener(java.beans.PropertyChangeListener listener) {
+ *         this$propertyChangeSupport.removePropertyChangeListener(listener)
+ *     }
+ * 
+ *     public void removePropertyChangeListener(java.lang.String name, java.beans.PropertyChangeListener listener) {
+ *         this$propertyChangeSupport.removePropertyChangeListener(name, listener)
+ *     }
+ * 
+ *     public void firePropertyChange(java.lang.String name, java.lang.Object oldValue, java.lang.Object newValue) {
+ *         this$propertyChangeSupport.firePropertyChange(name, oldValue, newValue)
+ *     }
+ * 
+ *     public java.beans.PropertyChangeListener[] getPropertyChangeListeners() {
+ *         return this$propertyChangeSupport.getPropertyChangeListeners()
+ *     }
+ * 
+ *     public java.beans.PropertyChangeListener[] getPropertyChangeListeners(java.lang.String name) {
+ *         return this$propertyChangeSupport.getPropertyChangeListeners(name)
+ *     }
+ * 
+ *     public void setFirstName(java.lang.String value) {
+ *         this.firePropertyChange('firstName', firstName, firstName = value )
+ *     }
+ * 
+ *     public void setZipCode(java.lang.Object value) {
+ *         this.firePropertyChange('zipCode', zipCode, zipCode = value )
+ *     }
+ * }
+ * </pre>
+ *
+ * @see BindableASTTransformation
+ * @author Danno Ferrin (shemnon)
+ */
+@java.lang.annotation.Documented
+@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.FIELD, ElementType.TYPE})
+@GroovyASTTransformationClass("groovy.beans.BindableASTTransformation")
+public @interface Bindable {
+}