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 04:29:18 UTC

[10/47] groovy git commit: Move source files to proper packages

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.groovy b/src/main/groovy/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.groovy
new file mode 100644
index 0000000..0605f18
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/transform/tailrec/TailRecursiveASTTransformation.groovy
@@ -0,0 +1,261 @@
+/*
+ *  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 org.codehaus.groovy.transform.tailrec
+
+import groovy.transform.CompileStatic
+import groovy.transform.Memoized
+import groovy.transform.TailRecursive
+import org.codehaus.groovy.ast.ASTNode
+import org.codehaus.groovy.ast.AnnotationNode
+import org.codehaus.groovy.ast.ClassHelper
+import org.codehaus.groovy.ast.ClassNode
+import org.codehaus.groovy.ast.MethodNode
+import org.codehaus.groovy.ast.Parameter
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.MethodCallExpression
+import org.codehaus.groovy.ast.expr.StaticMethodCallExpression
+import org.codehaus.groovy.ast.expr.TernaryExpression
+import org.codehaus.groovy.ast.expr.VariableExpression
+import org.codehaus.groovy.ast.stmt.BlockStatement
+import org.codehaus.groovy.ast.stmt.ReturnStatement
+import org.codehaus.groovy.ast.stmt.Statement
+import org.codehaus.groovy.classgen.ReturnAdder
+import org.codehaus.groovy.classgen.VariableScopeVisitor
+import org.codehaus.groovy.control.CompilePhase
+import org.codehaus.groovy.control.SourceUnit
+import org.codehaus.groovy.transform.AbstractASTTransformation
+import org.codehaus.groovy.transform.GroovyASTTransformation
+
+/**
+ * Handles generation of code for the @TailRecursive annotation.
+ *
+ * It's doing its work in the earliest possible compile phase
+ *
+ * @author Johannes Link
+ */
+@CompileStatic
+@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
+class TailRecursiveASTTransformation extends AbstractASTTransformation {
+
+    private static final Class MY_CLASS = TailRecursive.class;
+    private static final ClassNode MY_TYPE = new ClassNode(MY_CLASS);
+    static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage()
+    private HasRecursiveCalls hasRecursiveCalls = new HasRecursiveCalls()
+    private TernaryToIfStatementConverter ternaryToIfStatement = new TernaryToIfStatementConverter()
+
+
+    @Override
+    public void visit(ASTNode[] nodes, SourceUnit source) {
+        init(nodes, source);
+
+        MethodNode method = nodes[1] as MethodNode
+
+        if (method.isAbstract()) {
+            addError("Annotation " + MY_TYPE_NAME + " cannot be used for abstract methods.", method);
+            return;
+        }
+
+        if (hasAnnotation(method, ClassHelper.make(Memoized))) {
+            ClassNode memoizedClassNode = ClassHelper.make(Memoized)
+            for (AnnotationNode annotationNode in method.annotations) {
+                if (annotationNode.classNode == MY_TYPE)
+                    break
+                if (annotationNode.classNode == memoizedClassNode) {
+                    addError("Annotation " + MY_TYPE_NAME + " must be placed before annotation @Memoized.", annotationNode)
+                    return
+                }
+            }
+        }
+
+        if (!hasRecursiveMethodCalls(method)) {
+            AnnotationNode annotationNode = method.getAnnotations(ClassHelper.make(TailRecursive))[0]
+            addError("No recursive calls detected. You must remove annotation " + MY_TYPE_NAME + ".", annotationNode)
+            return;
+        }
+
+        transformToIteration(method, source)
+        ensureAllRecursiveCallsHaveBeenTransformed(method)
+    }
+
+    private boolean hasAnnotation(MethodNode methodNode, ClassNode annotation) {
+        List annots = methodNode.getAnnotations(annotation);
+        return (annots != null && annots.size() > 0);
+    }
+
+
+    private void transformToIteration(MethodNode method, SourceUnit source) {
+        if (method.isVoidMethod()) {
+            transformVoidMethodToIteration(method, source)
+        } else {
+            transformNonVoidMethodToIteration(method, source)
+        }
+    }
+
+    private void transformVoidMethodToIteration(MethodNode method, SourceUnit source) {
+        addError("Void methods are not supported by @TailRecursive yet.", method)
+    }
+
+    private void transformNonVoidMethodToIteration(MethodNode method, SourceUnit source) {
+        addMissingDefaultReturnStatement(method)
+        replaceReturnsWithTernariesToIfStatements(method)
+        wrapMethodBodyWithWhileLoop(method)
+
+        Map<String, Map> nameAndTypeMapping = name2VariableMappingFor(method)
+        replaceAllAccessToParams(method, nameAndTypeMapping)
+        addLocalVariablesForAllParameters(method, nameAndTypeMapping) //must happen after replacing access to params
+
+        Map<Integer, Map> positionMapping = position2VariableMappingFor(method)
+        replaceAllRecursiveReturnsWithIteration(method, positionMapping)
+        repairVariableScopes(source, method)
+    }
+
+    private void repairVariableScopes(SourceUnit source, MethodNode method) {
+        new VariableScopeVisitor(source).visitClass(method.declaringClass)
+    }
+
+    private void replaceReturnsWithTernariesToIfStatements(MethodNode method) {
+        Closure<Boolean> whenReturnWithTernary = { ASTNode node ->
+            if (!(node instanceof ReturnStatement)) {
+                return false
+            }
+            return (((ReturnStatement) node).expression instanceof TernaryExpression)
+        }
+        Closure<Statement> replaceWithIfStatement = { ReturnStatement statement ->
+            ternaryToIfStatement.convert(statement)
+        }
+        StatementReplacer replacer = new StatementReplacer(when: whenReturnWithTernary, replaceWith: replaceWithIfStatement)
+        replacer.replaceIn(method.code)
+
+    }
+
+    private void addLocalVariablesForAllParameters(MethodNode method, Map<String, Map> nameAndTypeMapping) {
+        BlockStatement code = method.code as BlockStatement
+        nameAndTypeMapping.each { String paramName, Map localNameAndType ->
+            code.statements.add(0, AstHelper.createVariableDefinition(
+                    (String) localNameAndType['name'],
+                    (ClassNode) localNameAndType['type'],
+                    new VariableExpression(paramName, (ClassNode) localNameAndType['type'])
+            ))
+        }
+    }
+
+    private void replaceAllAccessToParams(MethodNode method, Map<String, Map> nameAndTypeMapping) {
+        new VariableAccessReplacer(nameAndTypeMapping: nameAndTypeMapping).replaceIn(method.code)
+    }
+
+    // Public b/c there are tests for this method
+    Map<String, Map> name2VariableMappingFor(MethodNode method) {
+        Map<String, Map> nameAndTypeMapping = [:]
+        method.parameters.each { Parameter param ->
+            String paramName = param.name
+            ClassNode paramType = param.type as ClassNode
+            String iterationVariableName = iterationVariableName(paramName)
+            nameAndTypeMapping[paramName] = [name: iterationVariableName, type: paramType]
+        }
+        return nameAndTypeMapping
+    }
+
+    // Public b/c there are tests for this method
+    Map<Integer, Map> position2VariableMappingFor(MethodNode method) {
+        Map<Integer, Map> positionMapping = [:]
+        method.parameters.eachWithIndex { Parameter param, int index ->
+            String paramName = param.name
+            ClassNode paramType = param.type as ClassNode
+            String iterationVariableName = this.iterationVariableName(paramName)
+            positionMapping[index] = [name: iterationVariableName, type: paramType]
+        }
+        return positionMapping
+    }
+
+    private String iterationVariableName(String paramName) {
+        '_' + paramName + '_'
+    }
+
+    private void replaceAllRecursiveReturnsWithIteration(MethodNode method, Map positionMapping) {
+        replaceRecursiveReturnsOutsideClosures(method, positionMapping)
+        replaceRecursiveReturnsInsideClosures(method, positionMapping)
+    }
+
+    private void replaceRecursiveReturnsOutsideClosures(MethodNode method, Map<Integer, Map> positionMapping) {
+        Closure<Boolean> whenRecursiveReturn = { Statement statement, boolean inClosure ->
+            if (inClosure)
+                return false
+            if (!(statement instanceof ReturnStatement)) {
+                return false
+            }
+            Expression inner = ((ReturnStatement) statement).expression
+            if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
+                return false
+            }
+            return isRecursiveIn(inner, method)
+        }
+        Closure<Statement> replaceWithContinueBlock = { ReturnStatement statement ->
+            new ReturnStatementToIterationConverter().convert(statement, positionMapping)
+        }
+        def replacer = new StatementReplacer(when: whenRecursiveReturn, replaceWith: replaceWithContinueBlock)
+        replacer.replaceIn(method.code)
+    }
+
+    private void replaceRecursiveReturnsInsideClosures(MethodNode method, Map<Integer, Map> positionMapping) {
+        Closure<Boolean> whenRecursiveReturn = { Statement statement, boolean inClosure ->
+            if (!inClosure)
+                return false
+            if (!(statement instanceof ReturnStatement)) {
+                return false
+            }
+            Expression inner = ((ReturnStatement )statement).expression
+            if (!(inner instanceof MethodCallExpression) && !(inner instanceof StaticMethodCallExpression)) {
+                return false
+            }
+            return isRecursiveIn(inner, method)
+        }
+        Closure<Statement> replaceWithThrowLoopException = { ReturnStatement statement ->
+            new ReturnStatementToIterationConverter(recurStatement: AstHelper.recurByThrowStatement()).convert(statement, positionMapping)
+        }
+        StatementReplacer replacer = new StatementReplacer(when: whenRecursiveReturn, replaceWith: replaceWithThrowLoopException)
+        replacer.replaceIn(method.code)
+    }
+
+    private void wrapMethodBodyWithWhileLoop(MethodNode method) {
+        new InWhileLoopWrapper().wrap(method)
+    }
+
+    private void addMissingDefaultReturnStatement(MethodNode method) {
+        new ReturnAdder().visitMethod(method)
+        new ReturnAdderForClosures().visitMethod(method)
+    }
+
+    private void ensureAllRecursiveCallsHaveBeenTransformed(MethodNode method) {
+        List<Expression> remainingRecursiveCalls = new CollectRecursiveCalls().collect(method)
+        for(Expression expression : remainingRecursiveCalls) {
+            addError("Recursive call could not be transformed by @TailRecursive. Maybe it's not a tail call.", expression)
+        }
+    }
+
+    private boolean hasRecursiveMethodCalls(MethodNode method) {
+        hasRecursiveCalls.test(method)
+    }
+
+    private boolean isRecursiveIn(Expression methodCall, MethodNode method) {
+        if (methodCall instanceof MethodCallExpression)
+            return new RecursivenessTester().isRecursive(method, (MethodCallExpression) methodCall)
+        if (methodCall instanceof StaticMethodCallExpression)
+            return new RecursivenessTester().isRecursive(method, (StaticMethodCallExpression) methodCall)
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.groovy b/src/main/groovy/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.groovy
new file mode 100644
index 0000000..c47e1d2
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/transform/tailrec/TernaryToIfStatementConverter.groovy
@@ -0,0 +1,42 @@
+/*
+ *  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 org.codehaus.groovy.transform.tailrec
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.ast.expr.TernaryExpression
+import org.codehaus.groovy.ast.stmt.IfStatement
+import org.codehaus.groovy.ast.stmt.ReturnStatement
+import org.codehaus.groovy.ast.stmt.Statement
+
+/**
+ * Since a ternary statement has more than one exit point tail-recursiveness testing cannot be easily done.
+ * Therefore this class translates a ternary statement (or Elvis operator) into the equivalent if-else statement.
+ *
+ * @author Johannes Link
+ */
+@CompileStatic
+class TernaryToIfStatementConverter {
+
+    Statement convert(ReturnStatement statementWithInnerTernaryExpression) {
+        if (!(statementWithInnerTernaryExpression.expression instanceof TernaryExpression))
+            return statementWithInnerTernaryExpression
+        TernaryExpression ternary = statementWithInnerTernaryExpression.expression as TernaryExpression
+        return new IfStatement(ternary.booleanExpression, new ReturnStatement(ternary.trueExpression), new ReturnStatement(ternary.falseExpression))
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableAccessReplacer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableAccessReplacer.groovy b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableAccessReplacer.groovy
new file mode 100644
index 0000000..d62dc46
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableAccessReplacer.groovy
@@ -0,0 +1,73 @@
+/*
+ *  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 org.codehaus.groovy.transform.tailrec
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.ast.ASTNode
+import org.codehaus.groovy.ast.expr.VariableExpression
+
+/**
+ * Replace all access to variables and args by new variables.
+ * The variable names to replace as well as their replacement name and type have to be configured
+ * in nameAndTypeMapping before calling replaceIn().
+ *
+ * The VariableReplacedListener can be set if clients want to react to variable replacement.
+ *
+ * @author Johannes Link
+ */
+@CompileStatic
+class VariableAccessReplacer {
+
+    /**
+     * Nested map of variable accesses to replace
+     * e.g.: [
+     *          'varToReplace': [name: 'newVar', type: TypeOfVar],
+     *          'varToReplace2': [name: 'newVar2', type: TypeOfVar2],
+     *       ]
+     */
+    Map<String, Map> nameAndTypeMapping = [:]
+
+    VariableReplacedListener listener = VariableReplacedListener.NULL
+
+    void replaceIn(ASTNode root) {
+        Closure<Boolean> whenParam = { VariableExpression expr ->
+            return nameAndTypeMapping.containsKey(expr.name)
+        }
+        Closure<VariableExpression> replaceWithLocalVariable = { VariableExpression expr ->
+            Map nameAndType = nameAndTypeMapping[expr.name]
+            VariableExpression newVar = AstHelper.createVariableReference(nameAndType)
+            listener.variableReplaced(expr, newVar)
+            return newVar
+        }
+        new VariableExpressionReplacer(when: whenParam, replaceWith: replaceWithLocalVariable).replaceIn(root)
+    }
+
+}
+
+@CompileStatic
+interface VariableReplacedListener {
+    void variableReplaced(VariableExpression oldVar, VariableExpression newVar)
+
+    static VariableReplacedListener NULL = new VariableReplacedListener() {
+        @Override
+        void variableReplaced(VariableExpression oldVar, VariableExpression newVar) {
+            //do nothing
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.groovy b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.groovy
new file mode 100644
index 0000000..1f14490
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionReplacer.groovy
@@ -0,0 +1,171 @@
+/*
+ *  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 org.codehaus.groovy.transform.tailrec
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.ast.ASTNode
+import org.codehaus.groovy.ast.CodeVisitorSupport
+import org.codehaus.groovy.ast.expr.BinaryExpression
+import org.codehaus.groovy.ast.expr.BooleanExpression
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.ExpressionTransformer
+import org.codehaus.groovy.ast.expr.VariableExpression
+import org.codehaus.groovy.ast.stmt.AssertStatement
+import org.codehaus.groovy.ast.stmt.CaseStatement
+import org.codehaus.groovy.ast.stmt.DoWhileStatement
+import org.codehaus.groovy.ast.stmt.ExpressionStatement
+import org.codehaus.groovy.ast.stmt.ForStatement
+import org.codehaus.groovy.ast.stmt.IfStatement
+import org.codehaus.groovy.ast.stmt.ReturnStatement
+import org.codehaus.groovy.ast.stmt.SwitchStatement
+import org.codehaus.groovy.ast.stmt.SynchronizedStatement
+import org.codehaus.groovy.ast.stmt.ThrowStatement
+import org.codehaus.groovy.ast.stmt.WhileStatement
+
+import java.lang.reflect.Method
+
+/**
+ * Tool for replacing VariableExpression instances in an AST by other VariableExpression instances.
+ * Regardless of a real change taking place in nested expressions, all considered expression (trees) will be replaced.
+ * This could be optimized to accelerate compilation.
+ *
+ * Within @TailRecursive it is used
+ * - to swap the access of method args with the access to iteration variables
+ * - to swap the access of iteration variables with the access of temp vars
+ *
+ * @author Johannes Link
+ */
+@CompileStatic
+class VariableExpressionReplacer extends CodeVisitorSupport {
+
+    Closure<Boolean> when = { VariableExpression node -> false }
+    Closure<VariableExpression> replaceWith = { VariableExpression variableExpression -> variableExpression }
+
+    private ExpressionTransformer transformer
+
+    synchronized void replaceIn(ASTNode root) {
+        transformer = new VariableExpressionTransformer(when: when, replaceWith: replaceWith)
+        root.visit(this)
+    }
+
+    public void visitReturnStatement(ReturnStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitReturnStatement(statement);
+    }
+
+    public void visitIfElse(IfStatement ifElse) {
+        replaceExpressionPropertyWhenNecessary(ifElse, 'booleanExpression', BooleanExpression)
+        super.visitIfElse(ifElse);
+    }
+
+    public void visitForLoop(ForStatement forLoop) {
+        replaceExpressionPropertyWhenNecessary(forLoop, 'collectionExpression')
+        super.visitForLoop(forLoop);
+    }
+
+    /**
+     * It's the only Expression type in which replacing is considered.
+     * That's an abuse of the class, but I couldn't think of a better way.
+     */
+    public void visitBinaryExpression(BinaryExpression expression) {
+        //A hack: Only replace right expression b/c ReturnStatementToIterationConverter needs it that way :-/
+        replaceExpressionPropertyWhenNecessary(expression, 'rightExpression')
+        expression.getRightExpression().visit(this);
+        super.visitBinaryExpression(expression)
+    }
+
+    public void visitWhileLoop(WhileStatement loop) {
+        replaceExpressionPropertyWhenNecessary(loop, 'booleanExpression', BooleanExpression)
+        super.visitWhileLoop(loop);
+    }
+
+    public void visitDoWhileLoop(DoWhileStatement loop) {
+        replaceExpressionPropertyWhenNecessary(loop, 'booleanExpression', BooleanExpression)
+        super.visitDoWhileLoop(loop);
+    }
+
+    public void visitSwitch(SwitchStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitSwitch(statement)
+    }
+
+    public void visitCaseStatement(CaseStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitCaseStatement(statement)
+    }
+
+    public void visitExpressionStatement(ExpressionStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitExpressionStatement(statement);
+    }
+
+    public void visitThrowStatement(ThrowStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitThrowStatement(statement)
+    }
+
+    public void visitAssertStatement(AssertStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement, 'booleanExpression', BooleanExpression)
+        replaceExpressionPropertyWhenNecessary(statement, 'messageExpression')
+        super.visitAssertStatement(statement)
+    }
+
+    public void visitSynchronizedStatement(SynchronizedStatement statement) {
+        replaceExpressionPropertyWhenNecessary(statement)
+        super.visitSynchronizedStatement(statement)
+    }
+
+    private void replaceExpressionPropertyWhenNecessary(ASTNode node, String propName = "expression", Class propClass = Expression) {
+        Expression expr = getExpression(node, propName)
+
+        if (expr instanceof VariableExpression) {
+            if (when(expr)) {
+                VariableExpression newExpr = replaceWith(expr)
+                replaceExpression(node, propName, propClass, expr, newExpr)
+            }
+        } else {
+            Expression newExpr = expr.transformExpression(transformer)
+            replaceExpression(node, propName, propClass, expr, newExpr)
+        }
+    }
+
+    private void replaceExpression(ASTNode node, String propName, Class propClass, Expression oldExpr, Expression newExpr) {
+        //Use reflection to enable CompileStatic
+        String setterName = 'set' + capitalizeFirst(propName)
+        Method setExpressionMethod = node.class.getMethod(setterName, [propClass].toArray(new Class[1]))
+        newExpr.setSourcePosition(oldExpr);
+        newExpr.copyNodeMetaData(oldExpr);
+        setExpressionMethod.invoke(node, [newExpr].toArray())
+    }
+
+    private Expression getExpression(ASTNode node, String propName) {
+        //Use reflection to enable CompileStatic
+        String getterName = 'get' + capitalizeFirst(propName)
+        Method getExpressionMethod = node.class.getMethod(getterName, new Class[0])
+        getExpressionMethod.invoke(node, new Object[0]) as Expression
+    }
+
+    private String capitalizeFirst(String propName) {
+        propName[0].toUpperCase() + propName[1..-1]
+    }
+
+
+}
+
+

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionTransformer.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionTransformer.groovy b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionTransformer.groovy
new file mode 100644
index 0000000..106a2f1
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/transform/tailrec/VariableExpressionTransformer.groovy
@@ -0,0 +1,47 @@
+/*
+ *  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 org.codehaus.groovy.transform.tailrec
+
+import groovy.transform.CompileStatic
+import org.codehaus.groovy.ast.expr.Expression
+import org.codehaus.groovy.ast.expr.ExpressionTransformer
+import org.codehaus.groovy.ast.expr.VariableExpression
+
+/**
+ * An expression transformer used in the process of replacing the access to variables
+ *
+ * @author Johannes Link
+ */
+@CompileStatic
+class VariableExpressionTransformer implements ExpressionTransformer {
+
+    Closure<Boolean> when
+    Closure<VariableExpression> replaceWith
+
+    @Override
+    Expression transform(Expression expr) {
+        if ((expr instanceof VariableExpression) && when(expr)) {
+            VariableExpression newExpr = replaceWith(expr)
+            newExpr.setSourcePosition(expr);
+            newExpr.copyNodeMetaData(expr);
+            return newExpr
+        }
+        return expr.transformExpression(this)
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
----------------------------------------------------------------------
diff --git a/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy b/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
new file mode 100644
index 0000000..339d92c
--- /dev/null
+++ b/src/main/groovy/org/codehaus/groovy/util/StringUtil.groovy
@@ -0,0 +1,57 @@
+/*
+ *  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 org.codehaus.groovy.util
+
+import groovy.transform.CompileStatic
+
+/**
+ * String utility functions.
+ */
+@CompileStatic
+class StringUtil {
+    /**
+     * Provides Groovy with functionality similar to the unix tr command
+     * which translates a string replacing characters from a source set
+     * with characters from a replacement set.
+     *
+     * @since 1.7.3
+     */
+    static String tr(String text, String source, String replacement) {
+        if (!text || !source) { return text }
+        source = expandHyphen(source)
+        replacement = expandHyphen(replacement)
+
+        // padding replacement with a last character, if necessary
+        replacement = replacement.padRight(source.size(), replacement[replacement.size() - 1])
+
+        return text.collect { String original ->
+            if (source.contains(original)) {
+                replacement[source.lastIndexOf(original)]
+            } else {
+                original
+            }
+        }.join('')
+    }
+
+    // no expansion for hyphen at start or end of Strings
+    private static String expandHyphen(String text) {
+        if (!text.contains('-')) { return text }
+        return text.replaceAll(/(.)-(.)/, { all, begin, end -> (begin..end).join('') })
+    }
+}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/security/GroovyCodeSourcePermission.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/security/GroovyCodeSourcePermission.java b/src/main/groovy/security/GroovyCodeSourcePermission.java
deleted file mode 100644
index e723e0b..0000000
--- a/src/main/groovy/security/GroovyCodeSourcePermission.java
+++ /dev/null
@@ -1,40 +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.security;
-
-import java.security.BasicPermission;
-
-/**
- * Permission required to explicitly specify a codebase for a groovy script whose
- * codebase cannot be determined.  Typically this permission is only
- * required by clients that want to associate a code source with a script which
- * is a String or an InputStream.
- *
- * @author Steve Goetze
- */
-public final class GroovyCodeSourcePermission extends BasicPermission {
-
-    public GroovyCodeSourcePermission(String name) {
-        super(name);
-    }
-
-    public GroovyCodeSourcePermission(String name, String actions) {
-        super(name, actions);
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/security/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/security/package.html b/src/main/groovy/security/package.html
deleted file mode 100644
index cb094ff..0000000
--- a/src/main/groovy/security/package.html
+++ /dev/null
@@ -1,30 +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.
-
--->
-<html>
-  <head>
-    <title>package groovy.security.*</title>
-  </head>
-  <body>
-    <p>
-      Security-related classes
-    </p>
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/BaseDuration.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/BaseDuration.java b/src/main/groovy/time/BaseDuration.java
deleted file mode 100644
index e2cc023..0000000
--- a/src/main/groovy/time/BaseDuration.java
+++ /dev/null
@@ -1,141 +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.time;
-
-import org.codehaus.groovy.runtime.DefaultGroovyMethods;
-import org.codehaus.groovy.runtime.StringGroovyMethods;
-
-import java.util.ArrayList;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.List;
-
-/**
- * Base class for date and time durations.
- *
- * @author John Wilson tug@wilson.co.uk
- * @see Duration
- */
-public abstract class BaseDuration implements Comparable<BaseDuration> {
-    protected final int years;
-    protected final int months;
-    protected final int days;
-    protected final int hours;
-    protected final int minutes;
-    protected final int seconds;
-    protected final int millis;
-
-    protected BaseDuration(final int years, final int months, final int days, final int hours, final int minutes, final int seconds, final int millis) {
-        this.years = years;
-        this.months = months;
-        this.days = days;
-        this.hours = hours;
-        this.minutes = minutes;
-        this.seconds = seconds;
-        this.millis = millis;
-    }
-
-    protected BaseDuration(final int days, final int hours, final int minutes, final int seconds, final int millis) {
-        this(0, 0, days, hours, minutes, seconds, millis);
-    }
-
-    public int getYears() {
-        return this.years;
-    }
-
-    public int getMonths() {
-        return this.months;
-    }
-
-    public int getDays() {
-        return this.days;
-    }
-
-    public int getHours() {
-        return this.hours;
-    }
-
-    public int getMinutes() {
-        return this.minutes;
-    }
-
-    public int getSeconds() {
-        return this.seconds;
-    }
-
-    public int getMillis() {
-        return this.millis;
-    }
-
-    public Date plus(final Date date) {
-        final Calendar cal = Calendar.getInstance();
-
-        cal.setTime(date);
-        cal.add(Calendar.YEAR, this.years);
-        cal.add(Calendar.MONTH, this.months);
-        cal.add(Calendar.DAY_OF_YEAR, this.days);
-        cal.add(Calendar.HOUR_OF_DAY, this.hours);
-        cal.add(Calendar.MINUTE, this.minutes);
-        cal.add(Calendar.SECOND, this.seconds);
-        cal.add(Calendar.MILLISECOND, this.millis);
-
-        return cal.getTime();
-    }
-
-    public String toString() {
-        List buffer = new ArrayList();
-
-        if (this.years != 0) buffer.add(this.years + " years");
-        if (this.months != 0) buffer.add(this.months + " months");
-        if (this.days != 0) buffer.add(this.days + " days");
-        if (this.hours != 0) buffer.add(this.hours + " hours");
-        if (this.minutes != 0) buffer.add(this.minutes + " minutes");
-
-        if (this.seconds != 0 || this.millis != 0) {
-            int norm_millis = this.millis % 1000;
-            int norm_seconds = this.seconds + DefaultGroovyMethods.intdiv(this.millis - norm_millis, 1000).intValue();
-            CharSequence millisToPad = "" + Math.abs(norm_millis);
-            buffer.add((norm_seconds == 0 ? (norm_millis < 0 ? "-0" : "0") : norm_seconds) + "." + StringGroovyMethods.padLeft(millisToPad, 3, "0") + " seconds");
-        }
-
-        if (!buffer.isEmpty()) {
-            return DefaultGroovyMethods.join(buffer.iterator(), ", ");
-        } else {
-            return "0";
-        }
-    }
-
-    public abstract long toMilliseconds();
-
-    public abstract Date getAgo();
-
-    public abstract From getFrom();
-
-    public int compareTo(BaseDuration otherDuration) {
-        return Long.signum(toMilliseconds() - otherDuration.toMilliseconds());
-    }
-
-    public abstract static class From {
-        public abstract Date getNow();
-
-        public Date getToday() {
-            return getNow();
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/DatumDependentDuration.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/DatumDependentDuration.java b/src/main/groovy/time/DatumDependentDuration.java
deleted file mode 100644
index c73d9aa..0000000
--- a/src/main/groovy/time/DatumDependentDuration.java
+++ /dev/null
@@ -1,141 +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.time;
-
-import java.util.Calendar;
-import java.util.Date;
-
-/**
- * DatumDependentDuration represents durations whose length in milliseconds 
- * cannot be determined without knowing the datum point.
- * <p>
- * I don't know how many days in a year unless I know if it's a leap year or not.
- * <p>
- * I don't know how many days in a month unless I know the name of the month 
- * (and if it's a leap year if the month is February)
- *
- * @author John Wilson tug@wilson.co.uk
- */
-public class DatumDependentDuration extends BaseDuration {
-    public DatumDependentDuration(final int years, final int months, final int days, final int hours, final int minutes, final int seconds, final int millis) {
-        super(years, months, days, hours, minutes, seconds, millis);
-    }
-
-    public int getMonths() {
-        return this.months;
-    }
-
-    public int getYears() {
-        return this.years;
-    }
-
-    public DatumDependentDuration plus(final DatumDependentDuration rhs) {
-        return new DatumDependentDuration(this.getYears() + rhs.getYears(), this.getMonths() + rhs.getMonths(),
-                this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                this.getMillis() + rhs.getMillis());
-    }
-
-    public DatumDependentDuration plus(final TimeDatumDependentDuration rhs) {
-        return rhs.plus(this);
-    }
-
-    public DatumDependentDuration plus(final Duration rhs) {
-        return new DatumDependentDuration(this.getYears(), this.getMonths(),
-                this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                this.getMillis() + rhs.getMillis());
-
-    }
-
-    public DatumDependentDuration plus(final TimeDuration rhs) {
-        return rhs.plus(this);
-
-    }
-
-    public DatumDependentDuration minus(final DatumDependentDuration rhs) {
-        return new DatumDependentDuration(this.getYears() - rhs.getYears(), this.getMonths() - rhs.getMonths(),
-                this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                this.getMillis() - rhs.getMillis());
-
-    }
-
-    public DatumDependentDuration minus(final Duration rhs) {
-        return new DatumDependentDuration(this.getYears(), this.getMonths(),
-                this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                this.getMillis() - rhs.getMillis());
-
-    }
-
-    /**
-     * @see groovy.time.BaseDuration#toMilliseconds()
-     *
-     * Change the duration into milliseconds, relative to 'now.'  Therefore
-     * things like timezone and time of year will affect how this conversion 
-     * occurs.
-     */
-    public long toMilliseconds() {
-        final Date now = new Date();
-        return TimeCategory.minus(plus(now), now).toMilliseconds();
-    }
-
-    public Date getAgo() {
-        final Calendar cal = Calendar.getInstance();
-
-        cal.add(Calendar.YEAR, -this.getYears());
-        cal.add(Calendar.MONTH, -this.getMonths());
-        cal.add(Calendar.DAY_OF_YEAR, -this.getDays());
-        cal.add(Calendar.HOUR_OF_DAY, -this.getHours());
-        cal.add(Calendar.MINUTE, -this.getMinutes());
-        cal.add(Calendar.SECOND, -this.getSeconds());
-        cal.add(Calendar.MILLISECOND, -this.getMillis());
-
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-
-        return new Date(cal.getTimeInMillis());
-    }
-
-    public From getFrom() {
-        return new From() {
-            public Date getNow() {
-                final Calendar cal = Calendar.getInstance();
-
-                cal.add(Calendar.YEAR, DatumDependentDuration.this.getYears());
-                cal.add(Calendar.MONTH, DatumDependentDuration.this.getMonths());
-                cal.add(Calendar.DAY_OF_YEAR, DatumDependentDuration.this.getDays());
-                cal.add(Calendar.HOUR_OF_DAY, DatumDependentDuration.this.getHours());
-                cal.add(Calendar.MINUTE, DatumDependentDuration.this.getMinutes());
-                cal.add(Calendar.SECOND, DatumDependentDuration.this.getSeconds());
-                cal.add(Calendar.MILLISECOND, DatumDependentDuration.this.getMillis());
-
-                cal.set(Calendar.HOUR_OF_DAY, 0);
-                cal.set(Calendar.MINUTE, 0);
-                cal.set(Calendar.SECOND, 0);
-                cal.set(Calendar.MILLISECOND, 0);
-
-                return new Date(cal.getTimeInMillis());
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/Duration.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/Duration.java b/src/main/groovy/time/Duration.java
deleted file mode 100644
index e187957..0000000
--- a/src/main/groovy/time/Duration.java
+++ /dev/null
@@ -1,119 +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.time;
-
-import java.util.Calendar;
-import java.util.Date;
-
-/**
- * Duration represents time periods which have values independent of the context.
- * So, whilst we can't say how long a month is without knowing the year and the name of the month,
- * we know how long a day is independent of the date.
- * <p>
- * This is not 100% true for days.
- * Days can actually be 23, 24 or 25 hours long (due to daylight saving adjustments.)
- * <p>
- * If you ask Duration to convert itself to milliseconds then it will work on the basis of 24 hours
- * in a day. If you add or subtract it from a date it will take daylight saving into account.
- *
- * @author John Wilson tug@wilson.co.uk
- */
-public class Duration extends BaseDuration {
-    public Duration(final int days, final int hours, final int minutes, final int seconds, final int millis) {
-        super(days, hours, minutes, seconds, millis);
-    }
-    
-    public Duration plus(final Duration rhs) {
-        return new Duration(this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                            this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                            this.getMillis() + rhs.getMillis());
-    }
-
-    public Duration plus(final TimeDuration rhs) {
-        return rhs.plus(this);
-    }
-    
-    public DatumDependentDuration plus(final DatumDependentDuration rhs) {
-        return rhs.plus(this);
-    }
-    
-    public Duration minus(final Duration rhs) {
-        return new Duration(this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                            this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                            this.getMillis() - rhs.getMillis());
-    }
-    
-    public TimeDuration minus(final TimeDuration rhs) {
-        return new TimeDuration(this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                this.getMillis() - rhs.getMillis());
-    }
-    
-    public DatumDependentDuration minus(final DatumDependentDuration rhs) {
-        return new DatumDependentDuration(-rhs.getYears(), -rhs.getMonths(),
-                                          this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                          this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                          this.getMillis() - rhs.getMillis());
-    }
-    
-    public TimeDatumDependentDuration minus(final TimeDatumDependentDuration rhs) {
-        return new TimeDatumDependentDuration(-rhs.getYears(), -rhs.getMonths(),
-                                              this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                              this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                              this.getMillis() - rhs.getMillis());
-    }
-    
-    public long toMilliseconds() {
-        return ((((((long)(this.getDays() * 24 ) + this.getHours()) * 60 + this.getMinutes()) * 60) + this.getSeconds()) * 1000) + this.getMillis();
-    }
-    
-    public Date getAgo() {
-    final Calendar cal = Calendar.getInstance();
-
-        cal.add(Calendar.DAY_OF_YEAR, -this.getDays());
-        cal.add(Calendar.HOUR_OF_DAY, -this.getHours());
-        cal.add(Calendar.MINUTE, -this.getMinutes());
-        cal.add(Calendar.SECOND, -this.getSeconds());
-        cal.add(Calendar.MILLISECOND, -this.getMillis());
-
-        cal.set(Calendar.HOUR_OF_DAY, 0);
-        cal.set(Calendar.MINUTE, 0);
-        cal.set(Calendar.SECOND, 0);
-        cal.set(Calendar.MILLISECOND, 0);
-        
-        return new Date(cal.getTimeInMillis());
-    }
-     
-    public From getFrom() {
-        return new From() {
-            public Date getNow() {
-            final Calendar cal = Calendar.getInstance();
-
-                cal.add(Calendar.DAY_OF_YEAR, Duration.this.getDays());
-
-                cal.set(Calendar.HOUR_OF_DAY, 0);
-                cal.set(Calendar.MINUTE, 0);
-                cal.set(Calendar.SECOND, 0);
-                cal.set(Calendar.MILLISECOND, 0);
-
-                return new Date(cal.getTimeInMillis());
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/TimeCategory.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/TimeCategory.java b/src/main/groovy/time/TimeCategory.java
deleted file mode 100644
index dbc08cd..0000000
--- a/src/main/groovy/time/TimeCategory.java
+++ /dev/null
@@ -1,203 +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.time;
-
-import java.util.Calendar;
-import java.util.Date;
-import java.util.TimeZone;
-
-/**
- * Apply a number of methods to allow convenient Date/Time manipulation,such as:
- * <pre class="groovyTestCase">
- * use (groovy.time.TimeCategory) {
- *     // application on numbers:
- *     println 1.minute.from.now
- *     println 10.hours.ago
- *
- *     // application on dates
- *     def someDate = new Date()
- *     println someDate - 3.months
- * }
- * </pre>
- *
- * @see BaseDuration
- */
-public class TimeCategory {
-    /*
-     * Methods to allow Date Duration arithmetic
-     */
-
-    public static Date plus(final Date date, final BaseDuration duration) {
-        return duration.plus(date);
-    }
-
-    public static Date minus(final Date date, final BaseDuration duration) {
-        final Calendar cal = Calendar.getInstance();
-
-        cal.setTime(date);
-        cal.add(Calendar.YEAR, -duration.getYears());
-        cal.add(Calendar.MONTH, -duration.getMonths());
-        cal.add(Calendar.DAY_OF_YEAR, -duration.getDays());
-        cal.add(Calendar.HOUR_OF_DAY, -duration.getHours());
-        cal.add(Calendar.MINUTE, -duration.getMinutes());
-        cal.add(Calendar.SECOND, -duration.getSeconds());
-        cal.add(Calendar.MILLISECOND, -duration.getMillis());
-
-        return cal.getTime();
-    }
-
-    /**
-     * Retrieves the default TimeZone for a date by using the default Locale
-     * settings. Recommended that you use {@code TimeZone.getDefault()} instead.
-     *
-     * @param self a Date
-     * @return the TimeZone
-     */
-    @Deprecated
-    public static TimeZone getTimeZone(Date self) {
-        Calendar calendar = Calendar.getInstance();
-        calendar.setTime(self);
-        return calendar.getTimeZone();
-    }
-
-    /**
-     * Get the DST offset (if any) for the default locale and the given date.
-     *
-     * @param self a Date
-     * @return the DST offset as a Duration.
-     */
-    public static Duration getDaylightSavingsOffset(Date self) {
-        TimeZone timeZone = getTimeZone(self);
-        int millis = (timeZone.useDaylightTime() && timeZone.inDaylightTime(self))
-                ? timeZone.getDSTSavings() : 0;
-        return new TimeDuration(0, 0, 0, millis);
-    }
-
-    public static Duration getDaylightSavingsOffset(BaseDuration self) {
-        return getDaylightSavingsOffset(new Date(self.toMilliseconds() + 1));
-    }
-
-    /**
-     * Return a Duration representing the DST difference (if any) between two
-     * dates.  i.e. if one date is before the DST changeover, and the other
-     * date is after, the resulting duration will represent the DST offset.
-     *
-     * @param self  a Date
-     * @param other another Date
-     * @return a Duration
-     */
-    public static Duration getRelativeDaylightSavingsOffset(Date self, Date other) {
-        Duration d1 = getDaylightSavingsOffset(self);
-        Duration d2 = getDaylightSavingsOffset(other);
-        return new TimeDuration(0, 0, 0, (int) (d2.toMilliseconds() - d1.toMilliseconds()));
-    }
-
-    /**
-     * Subtract one date from the other.
-     *
-     * @param lhs a Date
-     * @param rhs another Date
-     * @return a Duration
-     */
-    public static TimeDuration minus(final Date lhs, final Date rhs) {
-        long milliseconds = lhs.getTime() - rhs.getTime();
-        long days = milliseconds / (24 * 60 * 60 * 1000);
-        milliseconds -= days * 24 * 60 * 60 * 1000;
-        int hours = (int) (milliseconds / (60 * 60 * 1000));
-        milliseconds -= hours * 60 * 60 * 1000;
-        int minutes = (int) (milliseconds / (60 * 1000));
-        milliseconds -= minutes * 60 * 1000;
-        int seconds = (int) (milliseconds / 1000);
-        milliseconds -= seconds * 1000;
-
-        return new TimeDuration((int) days, hours, minutes, seconds, (int) milliseconds);
-    }
-
-    /*
-    * Methods on Integer to implement 1.month, 4.years etc.
-    */
-
-    public static DatumDependentDuration getMonths(final Integer self) {
-        return new DatumDependentDuration(0, self, 0, 0, 0, 0, 0);
-    }
-
-    public static DatumDependentDuration getMonth(final Integer self) {
-        return getMonths(self);
-    }
-
-    public static DatumDependentDuration getYears(final Integer self) {
-        return new DatumDependentDuration(self, 0, 0, 0, 0, 0, 0);
-    }
-
-    public static DatumDependentDuration getYear(final Integer self) {
-        return getYears(self);
-    }
-
-    /*
-    * Methods on Integer to implement 1.week, 4.days etc.
-    */
-
-    public static Duration getWeeks(final Integer self) {
-        return new Duration(self * 7, 0, 0, 0, 0);
-    }
-
-    public static Duration getWeek(final Integer self) {
-        return getWeeks(self);
-    }
-
-    public static Duration getDays(final Integer self) {
-        return new Duration(self, 0, 0, 0, 0);
-    }
-
-    public static Duration getDay(final Integer self) {
-        return getDays(self);
-    }
-
-    public static TimeDuration getHours(final Integer self) {
-        return new TimeDuration(0, self, 0, 0, 0);
-    }
-
-    public static TimeDuration getHour(final Integer self) {
-        return getHours(self);
-    }
-
-    public static TimeDuration getMinutes(final Integer self) {
-        return new TimeDuration(0, 0, self, 0, 0);
-    }
-
-    public static TimeDuration getMinute(final Integer self) {
-        return getMinutes(self);
-    }
-
-    public static TimeDuration getSeconds(final Integer self) {
-        return new TimeDuration(0, 0, 0, self, 0);
-    }
-
-    public static TimeDuration getSecond(final Integer self) {
-        return getSeconds(self);
-    }
-
-    public static TimeDuration getMilliseconds(final Integer self) {
-        return new TimeDuration(0, 0, 0, 0, self);
-    }
-
-    public static TimeDuration getMillisecond(final Integer self) {
-        return getMilliseconds(self);
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/TimeDatumDependentDuration.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/TimeDatumDependentDuration.java b/src/main/groovy/time/TimeDatumDependentDuration.java
deleted file mode 100644
index eead45a..0000000
--- a/src/main/groovy/time/TimeDatumDependentDuration.java
+++ /dev/null
@@ -1,81 +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.time;
-
-import java.util.Calendar;
-import java.util.Date;
-
-/**
- * TimeDatumDuration represents a time period which results from an
- * arithmetic operation between a TimeDuration object and a DatumDuration object
- * 
- * @author John Wilson tug@wilson.co.uk
- */
-public class TimeDatumDependentDuration extends DatumDependentDuration {
-    public TimeDatumDependentDuration(int years, int months, int days, int hours, int minutes, int seconds, int millis) {
-        super(years, months, days, hours, minutes, seconds, millis);
-    }
-    
-    public DatumDependentDuration plus(final Duration rhs) {
-        return new TimeDatumDependentDuration(this.getYears(), this.getMonths(),
-                                              this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                                              this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                                              this.getMillis() + rhs.getMillis());
-    }
-    
-    public DatumDependentDuration plus(final DatumDependentDuration rhs) {
-        return new TimeDatumDependentDuration(this.getYears() + rhs.getYears(), this.getMonths() + rhs.getMonths(),
-                                              this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                                              this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                                              this.getMillis() + rhs.getMillis());
-    }
-    
-    public DatumDependentDuration minus(final Duration rhs) {
-        return new TimeDatumDependentDuration(this.getYears(), this.getMonths(),
-                                              this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                              this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                              this.getMillis() - rhs.getMillis());
-    }
-    
-    public DatumDependentDuration minus(final DatumDependentDuration rhs) {
-        return new TimeDatumDependentDuration(this.getYears() - rhs.getYears(), this.getMonths() - rhs.getMonths(),
-                                              this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                              this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                              this.getMillis() - rhs.getMillis());
-    }
-    
-    public From getFrom() {
-        return new From() {
-            public Date getNow() {
-            final Calendar cal = Calendar.getInstance();
-
-                cal.add(Calendar.YEAR, TimeDatumDependentDuration.this.getYears());
-                cal.add(Calendar.MONTH, TimeDatumDependentDuration.this.getMonths());
-                cal.add(Calendar.DAY_OF_YEAR, TimeDatumDependentDuration.this.getDays());
-                cal.add(Calendar.HOUR_OF_DAY, TimeDatumDependentDuration.this.getHours());
-                cal.add(Calendar.MINUTE, TimeDatumDependentDuration.this.getMinutes());
-                cal.add(Calendar.SECOND, TimeDatumDependentDuration.this.getSeconds());
-                cal.add(Calendar.MILLISECOND, TimeDatumDependentDuration.this.getMillis());
-                
-                return cal.getTime();
-            }
-        };
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/TimeDuration.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/TimeDuration.java b/src/main/groovy/time/TimeDuration.java
deleted file mode 100644
index 767b8e6..0000000
--- a/src/main/groovy/time/TimeDuration.java
+++ /dev/null
@@ -1,102 +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.time;
-
-import java.util.Calendar;
-import java.util.Date;
-
-/**
- * TimeDuration represents time periods expressed in units of hours, minutes,
- * seconds and milliseconds.
- * <p>
- * Whilst we can't say how long a month is without knowing the year and the name of the month,
- * we know how long a second is independent of the date.
- * <p>
- * This is not 100% true for minutes.
- * Minutes can be 59, 60 or 61 seconds long (due to leap seconds.)
- * <p>
- * If you ask Duration to convert itself to milliseconds then it will work on the basis of 60 seconds in a minute.
- * If you add or subtract it from a date it will take leap seconds into account.
- *
- * @author John Wilson tug@wilson.co.uk
- */
-
-public class TimeDuration extends Duration {
-    public TimeDuration(final int hours, final int minutes, final int seconds, final int millis) {
-        super(0, hours, minutes, seconds, millis);
-     }
-    
-    public TimeDuration(final int days, final int hours, final int minutes, final int seconds, final int millis) {
-        super(days, hours, minutes, seconds, millis);
-     }
-    
-    public Duration plus(final Duration rhs) {
-        return new TimeDuration(this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                                this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                                this.getMillis() + rhs.getMillis());
-    }
-    
-    public DatumDependentDuration plus(final DatumDependentDuration rhs) {
-        return new TimeDatumDependentDuration(rhs.getYears(), rhs.getMonths(),
-                                              this.getDays() + rhs.getDays(), this.getHours() + rhs.getHours(),
-                                              this.getMinutes() + rhs.getMinutes(), this.getSeconds() + rhs.getSeconds(),
-                                              this.getMillis() + rhs.getMillis());
-    }
-    
-    public Duration minus(final Duration rhs) {
-        return new TimeDuration(this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                this.getMillis() - rhs.getMillis());
-    }
-    
-    public DatumDependentDuration minus(final DatumDependentDuration rhs) {
-        return new TimeDatumDependentDuration(-rhs.getYears(), -rhs.getMonths(),
-                                              this.getDays() - rhs.getDays(), this.getHours() - rhs.getHours(),
-                                              this.getMinutes() - rhs.getMinutes(), this.getSeconds() - rhs.getSeconds(),
-                                              this.getMillis() - rhs.getMillis());
-    }
-    
-    public Date getAgo() {
-        final Calendar cal = Calendar.getInstance();
-
-        cal.add(Calendar.DAY_OF_YEAR, -this.getDays());
-        cal.add(Calendar.HOUR_OF_DAY, -this.getHours());
-        cal.add(Calendar.MINUTE, -this.getMinutes());
-        cal.add(Calendar.SECOND, -this.getSeconds());
-        cal.add(Calendar.MILLISECOND, -this.getMillis());
-        
-        return cal.getTime();
-    }        
-
-    public From getFrom() {
-        return new From() {
-            public Date getNow() {
-                final Calendar cal = Calendar.getInstance();
-
-                cal.add(Calendar.DAY_OF_YEAR, TimeDuration.this.getDays());
-                cal.add(Calendar.HOUR_OF_DAY, TimeDuration.this.getHours());
-                cal.add(Calendar.MINUTE, TimeDuration.this.getMinutes());
-                cal.add(Calendar.SECOND, TimeDuration.this.getSeconds());
-                cal.add(Calendar.MILLISECOND, TimeDuration.this.getMillis());
-                
-                return cal.getTime();
-            }
-        };
-    }
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/time/package.html
----------------------------------------------------------------------
diff --git a/src/main/groovy/time/package.html b/src/main/groovy/time/package.html
deleted file mode 100644
index 94fb458..0000000
--- a/src/main/groovy/time/package.html
+++ /dev/null
@@ -1,47 +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.
-
--->
-<html>
-  <head>
-    <title>package groovy.time.*</title>
-  </head>
-  <body>
-    <p>
-      Classes for easily manipulating Dates and times.  While 
-      <code>java.util.Date</code> has GDK methods for adding or subtracting days,
-      this is not so useful for different durations of time.  
-      {@link groovy.time.TimeCategory TimeCategory} creates a simple internal DSL
-      for manipulating dates and times in a clean and precise fashion.  
-    </p>
-    <h3>Examples</h3>
-    <pre>
-  use ( TimeCategory ) {
-  	// application on numbers:
-  	println 1.minute.from.now
-  	println 10.days.ago
-  
-  	// application on dates
-  	def someDate = new Date()
-  	println someDate - 3.months 
-  }</pre>
-     
-    @see groovy.time.TimeCategory
-  </body>
-</html>

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/ASTTest.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/ASTTest.java b/src/main/groovy/transform/ASTTest.java
deleted file mode 100644
index 1cdb480..0000000
--- a/src/main/groovy/transform/ASTTest.java
+++ /dev/null
@@ -1,71 +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.transform;
-
-import org.codehaus.groovy.control.CompilePhase;
-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;
-
-/**
- * This AST transformation aims at helping in debugging other AST transformations. It provides a basic
- * infrastructure for performing tests on AST nodes. You can place this annotation on any node which
- * accepts an annotation (types, methods, annotations, constructors, fields, local variables, packages
- * or parameters), then use a script which is run against this AST node at a specific phase. For example,
- * you could test the {@link Field} AST transformation this way:
- *
- * <pre class="groovyTestCase">
- * import groovy.transform.*
- *
- * {@code @ASTTest}(value = {
- *    def owner = node.declaringClass
- *    assert owner.fields.any { it.name == 'x' }
- *  })
- * {@code @Field int x}
- *
- * </pre>
- *
- * The closure code is executed after the specified phase has completed. If no phase is selected, then the
- * code is executed after the {@link org.codehaus.groovy.control.CompilePhase#SEMANTIC_ANALYSIS semantic analysis} phase.
- * The <code>node</code> variable refers to the AST node where the AST test annotation is put. In the previous example,
- * it means that <i>node</i> refers to the declaration node (int x).
- *
- * @author Cedric Champeau
- * @since 2.0.0
- *
- */
-@java.lang.annotation.Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD,
-ElementType.LOCAL_VARIABLE, ElementType.PACKAGE, ElementType.PARAMETER})
-@GroovyASTTransformationClass("org.codehaus.groovy.transform.ASTTestTransformation")
-public @interface ASTTest {
-    /**
-     * The compile phase after which the test code should run.
-     */
-    CompilePhase phase() default CompilePhase.SEMANTIC_ANALYSIS;
-
-    /**
-     * A closure which is executed against the annotated node after the specified phase has completed.
-     */
-    Class value();
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/AnnotationCollector.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/AnnotationCollector.java b/src/main/groovy/transform/AnnotationCollector.java
deleted file mode 100644
index b9f2161..0000000
--- a/src/main/groovy/transform/AnnotationCollector.java
+++ /dev/null
@@ -1,199 +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.transform;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * The AnnotationCollector can be used to define aliases for groups of 
- * annotations. The Alias needs to be a class or annotation annotated with 
- * AnnotationCollector, otherwise nothing is required. The alias will be 
- * replaced on the AST level and will never appear in later. Any members of the 
- * class or annotation will be ignored, but could be used by a custom processor.
- * Annotation arguments are mapped to the aliased annotations
- * if existing. Should the default processor not be able to map one of the
- * arguments and error will be given. Is this not wished or if you want a 
- * different mapping a custom processor has to be used. There are two ways of 
- * using the alias. The first way is by providing the annotations as list/array:
- * <pre class="groovyTestCase">
- *          import groovy.transform.*
- *          &#64;AnnotationCollector([ToString, EqualsAndHashCode, Immutable])
- *          &#64;interface Alias {}
-
- *          &#64;Alias(excludes=["a"])
- *          class Foo {
- *              Integer a, b
- *          }
- *          assert Foo.class.annotations.size()==3 
- *          assert new Foo(1,2).toString() == "Foo(2)"
- * </pre>
- * In the example above we have Alias as the alias annotation and an argument
- * excludes which will be mapped to ToString and EqualsAndHashCode. Immutable 
- * doesn't have excludes, thus nothing will be done there.<br>
- * The other way is to add annotations to the alias:
- * <pre class="groovyTestCase">
- * import groovy.transform.*
- * &#64;ToString(excludes=["a"])
- * &#64;EqualsAndHashCode
- * &#64;Immutable
- * &#64;AnnotationCollector
- * &#64;interface Alias {}
- *
- * &#64;Alias
- * class Foo {
- *     Integer a, b
- * }
- * assert Foo.class.annotations.size()==3
- * assert new Foo(1,2).toString() == "Foo(2)"
- * </pre>
- * In the example above we have again Alias as the alias annotation, but
- * this time the argument is part of the alias. Instead of mapping excludes to
- * ToString as well as EqualsAndHashCode, only ToString will have the excludes.
- * Again the alias can have an argument excludes, which would overwrite the 
- * excludes given in from the definition and be mapped to ToString as well as
- * EqualsAndHashCode.
- * If both ways are combined, then the list overwrites annotation usage.
- * NOTE: The aliasing does not support aliasing of aliased annotations. 
- * <p>More examples:</p>
- * <pre class="groovyTestCase">
- * //--------------------------------------------------------------------------
- * import groovy.transform.*
- * &#64;AnnotationCollector([EqualsAndHashCode, ToString])
- * &#64;interface Simple {}
- *
- *
- * &#64;Simple
- * class User {
- *     String username
- *     int age
- * }
- *
- * def user = new User(username: 'mrhaki', age: 39)
- * assert user.toString() == 'User(mrhaki, 39)'
- *
- * // We still have 2 annotations:
- * assert User.class.annotations.size() == 2
- *
- *
- * // We can use the attributes from the 
- * // grouped annotations.
- * &#64;Simple(excludes = 'street')
- * class Address {
- *     String street, town
- * }
- *
- * def address = new Address(street: 'Evergreen Terrace', town: 'Springfield') 
- * assert address.toString() == 'Address(Springfield)'
- * </pre>
- * <pre class="groovyTestCase">
- * //--------------------------------------------------------------------------
- * // Use a custom processor to handle attributes.
- * import org.codehaus.groovy.transform.*
- * import org.codehaus.groovy.ast.*
- * import org.codehaus.groovy.control.*
- *
- * class SimpleProcessor extends AnnotationCollectorTransform {
- *
- *     public List&lt;AnnotationNode&gt; visit(AnnotationNode collector, 
- *                                       AnnotationNode aliasAnnotationUsage, 
- *                                       AnnotatedNode aliasAnnotated, 
- *                                       SourceUnit source) {
- *
- *         // Get attributes and attribute value for dontUse.
- *         def attributes = aliasAnnotationUsage.getMembers()
- *         def dontUse = attributes.get('dontUse')
- *         attributes.remove('dontUse')
- *
- *         if (dontUse) {
- *             // Assign value of dontUse to excludes attributes.
- *             aliasAnnotationUsage.addMember("excludes", dontUse)
- *         }
- *
- *         super.visit(collector, aliasAnnotationUsage, aliasAnnotated, source)
- *     }
- *
- * }
- *
- * new GroovyShell(this.class.classLoader).evaluate '''
- * import groovy.transform.*
- *
- * &#64;AnnotationCollector(value = [EqualsAndHashCode, ToString], processor = 'SimpleProcessor')
- * &#64;interface Simple {}
- *
- *
- * &#64;Simple(dontUse = 'age')
- * class User {
- *     String username
- *     int age
- * }
- *
- * def user = new User(username: 'mrhaki', age: 39)
- * assert user.toString() == 'User(mrhaki)'
- * '''
- * </pre>
- * <pre class="groovyTestCase">
- * //--------------------------------------------------------------------------
- * // Use AnnotationCollector as last annotation to group the
- * // previous annotations.
- * import groovy.transform.*
- * &#64;EqualsAndHashCode
- * &#64;ToString
- * &#64;AnnotationCollector
- * &#64;interface Simple {}
- *
- *
- * &#64;Simple
- * class User {
- *     String username
- * }
- *
- * def user = new User(username: 'mrhaki')
- * assert user.toString() == 'User(mrhaki)'
- * </pre>
- * 
- * @author <a href="mailto:blackdrag@gmx.org">Jochen "blackdrag" Theodorou</a>
- * @see org.codehaus.groovy.transform.AnnotationCollectorTransform
- */
-@java.lang.annotation.Documented
-@Retention(RetentionPolicy.RUNTIME)
-@Target({ElementType.ANNOTATION_TYPE, ElementType.TYPE})
-public @interface AnnotationCollector {
-    /**
-     * Processor used for computing custom logic or the list of annotations, or 
-     * both. The default is org.codehaus.groovy.transform.AnnotationCollectorTransform.
-     * Custom processors need to extend that class. 
-     */
-    String processor() default "org.codehaus.groovy.transform.AnnotationCollectorTransform";
-
-    /**
-     * When the collector annotation is replaced, whether to check for duplicates between
-     * the replacement annotations and existing explicit annotations.
-     * If you use a custom processor, it is up to that processor whether it honors or ignores
-     * this parameter. The default processor honors the parameter.
-     */
-    AnnotationCollectorMode mode() default AnnotationCollectorMode.DUPLICATE;
-
-    /**
-     * List of aliased annotations.
-     */
-    Class[] value() default {};
-}

http://git-wip-us.apache.org/repos/asf/groovy/blob/0ad8c07c/src/main/groovy/transform/AnnotationCollectorMode.java
----------------------------------------------------------------------
diff --git a/src/main/groovy/transform/AnnotationCollectorMode.java b/src/main/groovy/transform/AnnotationCollectorMode.java
deleted file mode 100644
index 308d0c0..0000000
--- a/src/main/groovy/transform/AnnotationCollectorMode.java
+++ /dev/null
@@ -1,50 +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.transform;
-
-public enum AnnotationCollectorMode {
-    // TODO should we support @Repeatable from Java 8?
-    /**
-     * Annotations from the annotation collection will always be inserted. After all transforms have been run, it will
-     * be an error if multiple annotations (excluding those with SOURCE retention) exist.
-     */
-    DUPLICATE,
-
-    /**
-     * Annotations from the collector will be added and any existing annotations with the same name will be removed.
-     */
-    PREFER_COLLECTOR,
-
-    /**
-     * Annotations from the collector will be ignored if any existing annotations with the same name are found.
-     */
-    PREFER_EXPLICIT,
-
-    /**
-     * Annotations from the collector will be added and any existing annotations with the same name will be removed but any new parameters found within existing annotations will be merged into the added annotation.
-     */
-    PREFER_COLLECTOR_MERGED,
-
-    /**
-     * Annotations from the collector will be ignored if any existing annotations with the same name are found but any new parameters on the collector annotation will be added to existing annotations.
-     */
-    PREFER_EXPLICIT_MERGED
-}