You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2019/04/27 09:50:56 UTC

[groovy] 03/06: minor refactor: fix CRLF endings

This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_2_5_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 7eb3072a539fb3c67a57e2be48163b9c37ddecdb
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sat Apr 27 13:41:33 2019 +1000

    minor refactor: fix CRLF endings
---
 config/bnd/groovy-all.bnd                          |   38 +-
 config/bnd/groovy.bnd                              |   38 +-
 config/checkstyle/codeHeader.txt                   |   34 +-
 .../java/org/codehaus/groovy/antlr/EnumHelper.java |  136 +-
 .../groovy/classgen/AnnotationVisitor.java         |  628 ++---
 .../codehaus/groovy/classgen/BytecodeSequence.java |  162 +-
 .../codehaus/groovy/classgen/ExtendedVerifier.java |  682 +++---
 .../groovy/classgen/InnerClassVisitorHelper.java   |  286 +--
 .../groovy/control/SourceExtensionHandler.java     |  132 +-
 .../codehaus/groovy/reflection/ParameterTypes.java |  770 +++---
 .../codehaus/groovy/runtime/ConversionHandler.java |  452 ++--
 .../codehaus/groovy/runtime/ConvertedClosure.java  |  108 +-
 .../runtime/EncodingGroovyMethodsSupport.java      |  180 +-
 .../org/codehaus/groovy/runtime/GStringImpl.java   |  128 +-
 .../groovy/runtime/NumberAwareComparator.java      |  112 +-
 .../arrays/CharacterArrayPutAtMetaMethod.java      |  172 +-
 .../dgmimpl/arrays/ObjectArrayPutAtMetaMethod.java |  194 +-
 .../runtime/metaclass/ConcurrentReaderHashMap.java | 2542 ++++++++++----------
 .../metaclass/MethodSelectionException.java        |  202 +-
 .../runtime/typehandling/GroovyCastException.java  |  174 +-
 .../groovy/runtime/typehandling/package.html       |   60 +-
 .../org/codehaus/groovy/tools/StringHelper.java    |  172 +-
 .../groovy/transform/AbstractASTTransformUtil.java |  368 +--
 .../transform/AbstractASTTransformation.java       |  988 ++++----
 .../groovy/transform/FieldASTTransformation.java   |  584 ++---
 .../TupleConstructorASTTransformation.java         |  706 +++---
 .../codehaus/groovy/util/ComplexKeyHashMap.java    |  352 +--
 .../org/codehaus/groovy/util/SingleKeyHashMap.java |  322 +--
 .../org/codehaus/groovy/util/TripleKeyHashMap.java |  172 +-
 .../org/codehaus/groovy/vmplugin/VMPlugin.java     |  126 +-
 .../vmplugin/v5/PluginDefaultGroovyMethods.java    |  292 +--
 .../org/codehaus/groovy/vmplugin/v7/Java7.java     |  216 +-
 src/main/java/overview.html                        |   82 +-
 src/main/java/overviewj.html                       |   82 +-
 .../groovy/org.codehaus.groovy.source.Extensions   |   42 +-
 ...org.codehaus.groovy.transform.ASTTransformation |   40 +-
 .../services/org.codehaus.groovy.source.Extensions |   38 +-
 src/test/Outer3.groovy                             |   44 +-
 src/test/Outer4.groovy                             |   44 +-
 src/test/gls/CompilableTestSupport.groovy          |   80 +-
 src/test/gls/annotations/JavaAnnotation.java       |   54 +-
 src/test/gls/generics/GenericsTestBase.java        |  204 +-
 .../invocation/ConstructorDelegationTest.groovy    |  312 +--
 src/test/gls/invocation/MethodSelectionTest.groovy | 1014 ++++----
 src/test/gls/statements/DeclarationTest.groovy     |  100 +-
 src/test/gls/statements/ReturnTest.groovy          |  122 +-
 src/test/gls/syntax/AssertTest.groovy              |   58 +-
 .../gls/syntax/OldClosureSyntaxRemovalTest.groovy  |   88 +-
 .../gls/syntax/OldPropertySyntaxRemovalTest.groovy |   62 +-
 src/test/gls/syntax/OldSpreadTest.groovy           |   60 +-
 src/test/gls/syntax/ParsingTest.groovy             |  170 +-
 src/test/groovy/BinaryStreamsTest.groovy           |  334 +--
 src/test/groovy/ClosureJavaIntegrationTest.java    |  414 ++--
 src/test/groovy/ClosureMissingMethodTest.groovy    |  240 +-
 src/test/groovy/CompileOrderTest.groovy            |  164 +-
 src/test/groovy/FinallyTest.groovy                 |  300 +--
 .../groovy/GroovyCharSequenceMethodsTest.groovy    |  784 +++---
 src/test/groovy/JointGroovy.groovy                 |   60 +-
 src/test/groovy/JointJava.java                     |   54 +-
 src/test/groovy/KeywordsInPropertyNamesTest.groovy |  288 +--
 src/test/groovy/MethodInBadPositionTest.groovy     |   88 +-
 src/test/groovy/StaticMessageTest.groovy           |   76 +-
 src/test/groovy/ThisAndSuperTest.groovy            |  408 ++--
 src/test/groovy/annotations/MyClass.groovy         |   54 +-
 .../PackageAndImportAnnotationTest.groovy          |   80 +-
 src/test/groovy/annotations/package-info.groovy    |   38 +-
 src/test/groovy/bugs/G3839A1.java                  |   48 +-
 src/test/groovy/bugs/G3839A2.java                  |   50 +-
 src/test/groovy/bugs/G3839A3.java                  |   48 +-
 src/test/groovy/bugs/G3839A4.java                  |   50 +-
 src/test/groovy/bugs/G3839Transform1.java          |   70 +-
 src/test/groovy/bugs/G3839Transform2.java          |   70 +-
 src/test/groovy/bugs/G3839Transform3.java          |   70 +-
 src/test/groovy/bugs/G4410Producer1.java           |   48 +-
 src/test/groovy/bugs/G4410Producer2.java           |   50 +-
 src/test/groovy/bugs/Groovy1407_Bug.groovy         |   86 +-
 src/test/groovy/bugs/Groovy1465Bug.groovy          |  112 +-
 src/test/groovy/bugs/Groovy1593.groovy             |   64 +-
 src/test/groovy/bugs/Groovy1617_Bug.groovy         |   72 +-
 src/test/groovy/bugs/Groovy1706_Bug.groovy         |   82 +-
 src/test/groovy/bugs/Groovy2271Bug.groovy          |   94 +-
 src/test/groovy/bugs/Groovy2339Bug.groovy          |   68 +-
 src/test/groovy/bugs/Groovy2801Bug.groovy          |   60 +-
 src/test/groovy/bugs/Groovy2849Bug.groovy          |   84 +-
 src/test/groovy/bugs/Groovy2951Bug.groovy          |  106 +-
 src/test/groovy/bugs/Groovy3069Bug.groovy          |  124 +-
 src/test/groovy/bugs/Groovy3135Bug.groovy          |  150 +-
 src/test/groovy/bugs/Groovy3139Bug.groovy          |  112 +-
 src/test/groovy/bugs/Groovy3156And2621Bug.groovy   |  110 +-
 src/test/groovy/bugs/Groovy3205Bug.groovy          |   70 +-
 src/test/groovy/bugs/Groovy3238Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy3305Bug.groovy          |  106 +-
 src/test/groovy/bugs/Groovy3311Bug.groovy          |   66 +-
 src/test/groovy/bugs/Groovy3335Bug.groovy          |   54 +-
 src/test/groovy/bugs/Groovy3339Bug.groovy          |  110 +-
 src/test/groovy/bugs/Groovy3383Bug.groovy          |   62 +-
 src/test/groovy/bugs/Groovy3389Bug.groovy          |   70 +-
 src/test/groovy/bugs/Groovy3403Bug.groovy          |  118 +-
 src/test/groovy/bugs/Groovy3405Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy3410Bug.groovy          |  164 +-
 src/test/groovy/bugs/Groovy3462Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy3465Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy3465Helper.groovy       |   56 +-
 src/test/groovy/bugs/Groovy3498Bug.groovy          |   56 +-
 src/test/groovy/bugs/Groovy3511Bug.groovy          |  110 +-
 src/test/groovy/bugs/Groovy3560Bug.groovy          |   52 +-
 src/test/groovy/bugs/Groovy3560Helper.java         |   66 +-
 src/test/groovy/bugs/Groovy3574Bug.groovy          |  122 +-
 src/test/groovy/bugs/Groovy3590Bug.groovy          |   52 +-
 src/test/groovy/bugs/Groovy3596Bug.groovy          |   60 +-
 src/test/groovy/bugs/Groovy3645Bug.groovy          |   68 +-
 src/test/groovy/bugs/Groovy3658Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy3679Bug.groovy          |   96 +-
 src/test/groovy/bugs/Groovy3716Bug.groovy          |   58 +-
 src/test/groovy/bugs/Groovy3718Bug.groovy          |   62 +-
 src/test/groovy/bugs/Groovy3719Bug.groovy          |   62 +-
 src/test/groovy/bugs/Groovy3719Bug_script.groovy   |   38 +-
 src/test/groovy/bugs/Groovy3720Bug.groovy          |  128 +-
 src/test/groovy/bugs/Groovy3721Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy3723Bug.groovy          |   90 +-
 src/test/groovy/bugs/Groovy3726Bug.groovy          |  126 +-
 src/test/groovy/bugs/Groovy3731Bug.groovy          |   86 +-
 src/test/groovy/bugs/Groovy3749Bug.groovy          |  182 +-
 src/test/groovy/bugs/Groovy3768Bug.groovy          |  100 +-
 src/test/groovy/bugs/Groovy3770Bug.groovy          |  112 +-
 src/test/groovy/bugs/Groovy3776Bug.groovy          |   92 +-
 src/test/groovy/bugs/Groovy3784Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy3789Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy3799Bug.groovy          |   62 +-
 src/test/groovy/bugs/Groovy3799Helper.java         |   94 +-
 src/test/groovy/bugs/Groovy3801Bug.groovy          |  106 +-
 src/test/groovy/bugs/Groovy3817Bug.groovy          |   88 +-
 src/test/groovy/bugs/Groovy3818Bug.groovy          |   96 +-
 src/test/groovy/bugs/Groovy3827Bug.groovy          |   76 +-
 src/test/groovy/bugs/Groovy3830Bug.groovy          |  144 +-
 src/test/groovy/bugs/Groovy3831Bug.groovy          |  106 +-
 src/test/groovy/bugs/Groovy3834Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy3839Bug.groovy          |  148 +-
 src/test/groovy/bugs/Groovy3852Bug.groovy          |  214 +-
 src/test/groovy/bugs/Groovy3857Bug.groovy          |   60 +-
 src/test/groovy/bugs/Groovy3863Bug.groovy          |   62 +-
 src/test/groovy/bugs/Groovy3868Bug.groovy          |   80 +-
 src/test/groovy/bugs/Groovy3873Bug.groovy          |   66 +-
 src/test/groovy/bugs/Groovy3876Bug.groovy          |   84 +-
 src/test/groovy/bugs/Groovy3894Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy3904Bug.groovy          |  168 +-
 src/test/groovy/bugs/Groovy3949Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy3989Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy4006Bug.groovy          |  298 +--
 src/test/groovy/bugs/Groovy4009Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy4025Bug.groovy          |   84 +-
 src/test/groovy/bugs/Groovy4029Bug.groovy          |   54 +-
 src/test/groovy/bugs/Groovy4035Bug.groovy          |   96 +-
 src/test/groovy/bugs/Groovy4038Bug.groovy          |   56 +-
 src/test/groovy/bugs/Groovy4043Bug.groovy          |   68 +-
 src/test/groovy/bugs/Groovy4046Bug.groovy          |   58 +-
 src/test/groovy/bugs/Groovy4069Bug.groovy          |  268 +--
 src/test/groovy/bugs/Groovy4075Bug.groovy          |   82 +-
 src/test/groovy/bugs/Groovy4078Bug.groovy          |   98 +-
 src/test/groovy/bugs/Groovy4080Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4081Bug.groovy          |   76 +-
 src/test/groovy/bugs/Groovy4098Bug.groovy          |  296 +--
 src/test/groovy/bugs/Groovy4098Child.groovy        |   74 +-
 src/test/groovy/bugs/Groovy4098Parent.groovy       |   50 +-
 src/test/groovy/bugs/Groovy4104A.java              |   60 +-
 src/test/groovy/bugs/Groovy4104B.java              |   40 +-
 src/test/groovy/bugs/Groovy4104Bug.groovy          |   66 +-
 src/test/groovy/bugs/Groovy4106Bug.groovy          |   54 +-
 src/test/groovy/bugs/Groovy4107Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4111Bug.groovy          |   80 +-
 src/test/groovy/bugs/Groovy4116Bug.groovy          |  130 +-
 src/test/groovy/bugs/Groovy4119Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4120Bug.groovy          |  112 +-
 src/test/groovy/bugs/Groovy4121Bug.groovy          |   94 +-
 src/test/groovy/bugs/Groovy4129Bug.groovy          |   66 +-
 src/test/groovy/bugs/Groovy4131Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy4133Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy4134Bug.groovy          |   54 +-
 src/test/groovy/bugs/Groovy4139Bug.groovy          |   66 +-
 src/test/groovy/bugs/Groovy4145.groovy             |   48 +-
 src/test/groovy/bugs/Groovy4151Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy4169Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4170Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy4188Bug.groovy          |   76 +-
 src/test/groovy/bugs/Groovy4190Bug.groovy          |  102 +-
 src/test/groovy/bugs/Groovy4191Bug.groovy          |   60 +-
 src/test/groovy/bugs/Groovy4193Bug.groovy          |   60 +-
 src/test/groovy/bugs/Groovy4202Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4206Bug.groovy          |   68 +-
 src/test/groovy/bugs/Groovy4235Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy4241Bug.groovy          |   80 +-
 src/test/groovy/bugs/Groovy4243Bug.groovy          |   96 +-
 src/test/groovy/bugs/Groovy4246Bug.groovy          |   94 +-
 src/test/groovy/bugs/Groovy4247Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy4252Bug.groovy          |  170 +-
 src/test/groovy/bugs/Groovy4257Bug.groovy          |   80 +-
 src/test/groovy/bugs/Groovy4264Bug.groovy          |  138 +-
 src/test/groovy/bugs/Groovy4272Bug.groovy          |   64 +-
 src/test/groovy/bugs/Groovy4273Bug.groovy          |  130 +-
 src/test/groovy/bugs/Groovy4293Bug.groovy          |   80 +-
 src/test/groovy/bugs/Groovy4325Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4386_Bug.groovy         |  178 +-
 src/test/groovy/bugs/Groovy4393Bug.groovy          |   56 +-
 src/test/groovy/bugs/Groovy4393BugV1.foogroovy     |   40 +-
 src/test/groovy/bugs/Groovy4410Bug.groovy          |  124 +-
 src/test/groovy/bugs/Groovy4414Bug.groovy          |  138 +-
 src/test/groovy/bugs/Groovy4416Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy4435Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy4449Bug.groovy          |   88 +-
 src/test/groovy/bugs/Groovy4497Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy4516Bug.groovy          |   78 +-
 src/test/groovy/bugs/Groovy4584Bug.groovy          |   72 +-
 src/test/groovy/bugs/Groovy4607Bug.groovy          |  104 +-
 src/test/groovy/bugs/Groovy4861Bug.groovy          |   74 +-
 src/test/groovy/bugs/Groovy513_Bug.groovy          |   72 +-
 src/test/groovy/bugs/GroovyInnerEnumBug.groovy     |   94 +-
 .../groovy/grape/GrabErrorIsolationTest.groovy     |  112 +-
 src/test/groovy/grape/GrapeClassLoaderTest.groovy  |  568 ++---
 src/test/groovy/lang/CategoryAnnotationTest.groovy |  596 ++---
 src/test/groovy/lang/Groovy3406Test.groovy         |   52 +-
 .../groovy/lang/InnerClassResolvingTest.groovy     |  122 +-
 src/test/groovy/lang/StripMarginTest.groovy        |  186 +-
 .../groovy/mock/interceptor/HalfMockTest.groovy    |  284 +--
 .../groovy/mock/interceptor/IteratorCounter.java   |   52 +-
 .../groovy/mock/interceptor/MockForJavaTest.groovy |  108 +-
 .../mock/interceptor/MockNestedCallTest.groovy     |   90 +-
 .../groovy/mock/interceptor/StubForJavaTest.groovy |  100 +-
 src/test/groovy/util/ResourceBundleTest.groovy     |  154 +-
 src/test/groovy/util/i18n.properties               |   40 +-
 src/test/groovy/util/i18n_fr.properties            |   40 +-
 src/test/groovy/util/logging/LogTest.groovy        |  748 +++---
 .../codehaus/groovy/antlr/SourceParserTest.java    |  104 +-
 .../org/codehaus/groovy/ast/LineColumnCheck.txt    |  938 ++++----
 .../groovy/ast/expr/MapExpressionTest.groovy       |   88 +-
 .../groovy/classgen/ReflectorLoaderTest.groovy     |   64 +-
 .../groovy/control/CompilerConfigurationTest.java  |  460 ++--
 .../reflection/utils/PojoCallerTestClass.java      |   66 +-
 .../reflection/utils/ReflectionUtilsTest.groovy    |  192 +-
 .../groovy/runtime/MetaClassHelperTest.java        |   54 +-
 .../groovy/runtime/NestedCategoryTest.groovy       |  158 +-
 .../groovy/tools/LoaderConfigurationTest.groovy    |  276 +--
 .../codehaus/groovy/tools/StringHelperTest.groovy  |   70 +-
 .../org/codehaus/groovy/tools/UtilitiesTest.groovy |   84 +-
 .../AbstractGenericGroovySuperclass.groovy         |   68 +-
 .../rootloadersync/AbstractGroovySuperclass.groovy |   54 +-
 .../ConcreteGenericJavaSubclass.java               |   64 +-
 .../tools/rootloadersync/ConcreteJavaSubclass.java |   52 +-
 .../OtherConcreteGenericJavaSubclass.java          |   64 +-
 .../rootloadersync/OtherConcreteJavaSubclass.java  |   52 +-
 .../rootloadersync/SubclassingInGroovyTest.groovy  |   78 +-
 .../rootloadersync/SubclassingInJavaTest.java      |   82 +-
 .../groovy/transform/CanonicalTransformTest.groovy | 1184 ++++-----
 .../groovy/transform/FieldTransformTest.groovy     |  572 ++---
 .../groovy/transform/GlobalTransformTest.groovy    |   70 +-
 .../transform/IndexedPropertyTransformTest.groovy  |  148 +-
 .../groovy/transform/LazyTransformTest.groovy      |  446 ++--
 ...org.codehaus.groovy.transform.ASTTransformation |   34 +-
 .../groovy/transform/NewifyTransformTest.groovy    |  474 ++--
 .../transform/SingletonASTTransformationTest.java  |   94 +-
 .../codehaus/groovy/transform/TestTransform.groovy |   96 +-
 .../jmx/builder/JmxAttributeInfoManager.groovy     |  180 +-
 .../groovy/jmx/builder/JmxBeanExportFactory.groovy |  106 +-
 .../groovy/jmx/builder/JmxBeanFactory.groovy       |  326 +--
 .../groovy/jmx/builder/JmxBeanInfoManager.groovy   |  190 +-
 .../groovy/groovy/jmx/builder/JmxBuilder.groovy    |  208 +-
 .../groovy/jmx/builder/JmxBuilderTools.groovy      |  636 ++---
 .../jmx/builder/JmxClientConnectorFactory.groovy   |  146 +-
 .../groovy/jmx/builder/JmxEmitterFactory.groovy    |  222 +-
 .../groovy/jmx/builder/JmxListenerFactory.groovy   |  158 +-
 .../groovy/jmx/builder/JmxMetaMapBuilder.groovy    | 1294 +++++-----
 .../jmx/builder/JmxOperationInfoManager.groovy     |  436 ++--
 .../jmx/builder/JmxServerConnectorFactory.groovy   |  276 +--
 .../groovy/jmx/builder/JmxTimerFactory.groovy      |  396 +--
 .../groovy/groovy/jmx/builder/package-info.groovy  |   44 +-
 .../groovy/jmx/builder/JmxBuilderException.java    |  116 +-
 .../groovy/jmx/builder/JmxBuilderModelMBean.java   |  442 ++--
 .../java/groovy/jmx/builder/JmxEventEmitter.java   |  212 +-
 .../groovy/jmx/builder/JmxEventEmitterMBean.java   |   98 +-
 .../java/groovy/jmx/builder/JmxEventListener.java  |  160 +-
 .../jmx/builder/JmxAttributeInfoManagerTest.groovy |  126 +-
 .../jmx/builder/JmxBeanExportFactoryTest.groovy    | 1124 ++++-----
 .../groovy/jmx/builder/JmxBeanFactoryTest.groovy   |  184 +-
 .../jmx/builder/JmxBeanInfoManagerTest.groovy      |  148 +-
 .../groovy/jmx/builder/JmxBuilderToolsTest.groovy  |  260 +-
 .../builder/JmxClientConnectorFactoryTest.groovy   |  142 +-
 .../jmx/builder/JmxEmitterFactoryTest.groovy       |  198 +-
 .../jmx/builder/JmxListenerFactoryTest.groovy      |  122 +-
 .../jmx/builder/JmxMetaMapBuilderTest.groovy       | 1020 ++++----
 .../jmx/builder/JmxOperationInfoManagerTest.groovy |  376 +--
 .../builder/JmxServerConnectorFactoryTest.groovy   |  120 +-
 .../groovy/jmx/builder/JmxTimerFactoryTest.groovy  |  306 +--
 .../jmx/builder/MockManagedGroovyObject.groovy     |   74 +-
 .../groovy/jmx/builder/JmxConnectorHelper.java     |  132 +-
 .../java/groovy/jmx/builder/MockJmxListener.java   |   98 +-
 .../java/groovy/jmx/builder/MockManagedObject.java |  162 +-
 .../java/groovy/jmx/builder/MockSimpleObject.java  |   80 +-
 .../groovy/jmx/builder/MockSimpleObjectMBean.java  |   58 +-
 .../groovy/text/TemplateExecutionException.java    |  112 +-
 .../groovy/text/StreamingTemplateEngineTest.groovy |  924 +++----
 299 files changed, 25800 insertions(+), 25800 deletions(-)

diff --git a/config/bnd/groovy-all.bnd b/config/bnd/groovy-all.bnd
index 3de9d83..cab706f 100644
--- a/config/bnd/groovy-all.bnd
+++ b/config/bnd/groovy-all.bnd
@@ -1,19 +1,19 @@
-# 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.
-
-version= @GROOVY_BUNDLE_VERSION@
--nouses= true
-Export-Package= *;version=${version}
-Import-Package= *;resolution:=optional
+# 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.
+
+version= @GROOVY_BUNDLE_VERSION@
+-nouses= true
+Export-Package= *;version=${version}
+Import-Package= *;resolution:=optional
diff --git a/config/bnd/groovy.bnd b/config/bnd/groovy.bnd
index 2a5f8e3..f5df535 100644
--- a/config/bnd/groovy.bnd
+++ b/config/bnd/groovy.bnd
@@ -1,19 +1,19 @@
-# 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.
-
-version= @GROOVY_BUNDLE_VERSION@
--nouses= true
-Export-Package= *;version=${version}
-Import-Package= antlr, org.objectweb.asm, *;resolution:=optional
+# 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.
+
+version= @GROOVY_BUNDLE_VERSION@
+-nouses= true
+Export-Package= *;version=${version}
+Import-Package= antlr, org.objectweb.asm, *;resolution:=optional
diff --git a/config/checkstyle/codeHeader.txt b/config/checkstyle/codeHeader.txt
index 3673647..ca35f1a 100644
--- a/config/checkstyle/codeHeader.txt
+++ b/config/checkstyle/codeHeader.txt
@@ -1,18 +1,18 @@
-^/\*$
-^ \* ? 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\.$
+^/\*$
+^ \* ? 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\.$
 ^ \*.*
\ No newline at end of file
diff --git a/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java b/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
index 6f5fc3e..803bd0b 100644
--- a/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
+++ b/src/main/java/org/codehaus/groovy/antlr/EnumHelper.java
@@ -1,68 +1,68 @@
-/*
- *  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.antlr;
-
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.GenericsType;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.ast.MixinNode;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.objectweb.asm.Opcodes;
-
-public class EnumHelper {
-    private static final int FS = Opcodes.ACC_FINAL | Opcodes.ACC_STATIC;
-    private static final int PUBLIC_FS = Opcodes.ACC_PUBLIC | FS; 
-    
-    public static ClassNode makeEnumNode(String name, int modifiers, ClassNode[] interfaces, ClassNode outerClass) {
-        modifiers = modifiers | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM;
-        ClassNode enumClass;
-        if (outerClass==null) {
-            enumClass = new ClassNode(name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY);
-        } else {
-            name = outerClass.getName() + "$" + name;
-            modifiers |= Opcodes.ACC_STATIC;
-            enumClass = new InnerClassNode(outerClass,name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY);
-        }
-        
-        // set super class and generics info
-        // "enum X" -> class X extends Enum<X>
-        GenericsType gt = new GenericsType(enumClass);
-        ClassNode superClass = ClassHelper.makeWithoutCaching("java.lang.Enum");
-        superClass.setGenericsTypes(new GenericsType[]{gt});
-        enumClass.setSuperClass(superClass);
-        superClass.setRedirect(ClassHelper.Enum_Type);
-        
-        return enumClass;
-    }
-
-    public static FieldNode addEnumConstant(ClassNode enumClass, String name, Expression init) {
-        int modifiers = PUBLIC_FS | Opcodes.ACC_ENUM;
-        if (init != null && !(init instanceof ListExpression)) {
-            ListExpression list = new ListExpression();
-            list.addExpression(init);
-            init = list;
-        }
-        FieldNode fn = new FieldNode(name, modifiers, enumClass.getPlainNodeReference(), enumClass, init);
-        enumClass.addField(fn);
-        return fn;
-    }
-}
+/*
+ *  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.antlr;
+
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.InnerClassNode;
+import org.codehaus.groovy.ast.MixinNode;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.ListExpression;
+import org.objectweb.asm.Opcodes;
+
+public class EnumHelper {
+    private static final int FS = Opcodes.ACC_FINAL | Opcodes.ACC_STATIC;
+    private static final int PUBLIC_FS = Opcodes.ACC_PUBLIC | FS; 
+    
+    public static ClassNode makeEnumNode(String name, int modifiers, ClassNode[] interfaces, ClassNode outerClass) {
+        modifiers = modifiers | Opcodes.ACC_FINAL | Opcodes.ACC_ENUM;
+        ClassNode enumClass;
+        if (outerClass==null) {
+            enumClass = new ClassNode(name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY);
+        } else {
+            name = outerClass.getName() + "$" + name;
+            modifiers |= Opcodes.ACC_STATIC;
+            enumClass = new InnerClassNode(outerClass,name,modifiers,null,interfaces,MixinNode.EMPTY_ARRAY);
+        }
+        
+        // set super class and generics info
+        // "enum X" -> class X extends Enum<X>
+        GenericsType gt = new GenericsType(enumClass);
+        ClassNode superClass = ClassHelper.makeWithoutCaching("java.lang.Enum");
+        superClass.setGenericsTypes(new GenericsType[]{gt});
+        enumClass.setSuperClass(superClass);
+        superClass.setRedirect(ClassHelper.Enum_Type);
+        
+        return enumClass;
+    }
+
+    public static FieldNode addEnumConstant(ClassNode enumClass, String name, Expression init) {
+        int modifiers = PUBLIC_FS | Opcodes.ACC_ENUM;
+        if (init != null && !(init instanceof ListExpression)) {
+            ListExpression list = new ListExpression();
+            list.addExpression(init);
+            init = list;
+        }
+        FieldNode fn = new FieldNode(name, modifiers, enumClass.getPlainNodeReference(), enumClass, init);
+        enumClass.addField(fn);
+        return fn;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java b/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
index 46c471e..42eb463 100644
--- a/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
+++ b/src/main/java/org/codehaus/groovy/classgen/AnnotationVisitor.java
@@ -1,314 +1,314 @@
-/*
- *  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.classgen;
-
-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.FieldNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-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.PropertyExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.control.ErrorCollector;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.codehaus.groovy.vmplugin.VMPluginFactory;
-
-import java.util.List;
-import java.util.Map;
-
-import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
-
-/**
- * An Annotation visitor responsible for:
- * <ul>
- * <li>reading annotation metadata (@Retention, @Target, attribute types)</li>
- * <li>verify that an <code>AnnotationNode</code> conforms to annotation meta</li>
- * <li>enhancing an <code>AnnotationNode</code> AST to reflect real annotation meta</li>
- * </ul>
- */
-public class AnnotationVisitor {
-    private final SourceUnit source;
-    private final ErrorCollector errorCollector;
-    private AnnotationNode annotation;
-    private ClassNode reportClass;
-
-    public AnnotationVisitor(SourceUnit source, ErrorCollector errorCollector) {
-        this.source = source;
-        this.errorCollector = errorCollector;
-    }
-
-    public void setReportClass(ClassNode cn) {
-        reportClass = cn;
-    }
-
-    public AnnotationNode visit(AnnotationNode node) {
-        this.annotation = node;
-        this.reportClass = node.getClassNode();
-
-        if (!isValidAnnotationClass(node.getClassNode())) {
-            addError("class " + node.getClassNode().getName() + " is not an annotation");
-            return node;
-        }
-
-        // check if values have been passed for all annotation attributes that don't have defaults
-        if (!checkIfMandatoryAnnotationValuesPassed(node)) {
-            return node;
-        }
-
-        // if enum constants have been used, check if they are all valid
-        if (!checkIfValidEnumConstsAreUsed(node)) {
-            return node;
-        }
-        
-        Map<String, Expression> attributes = node.getMembers();
-        for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
-            String attrName = entry.getKey();
-            ClassNode attrType = getAttributeType(node, attrName);
-            Expression attrExpr = transformInlineConstants(entry.getValue(), attrType);
-            entry.setValue(attrExpr);
-            visitExpression(attrName, attrExpr, attrType);
-        }
-        VMPluginFactory.getPlugin().configureAnnotation(node);
-        return this.annotation;
-    }
-    
-    private boolean checkIfValidEnumConstsAreUsed(AnnotationNode node) {
-        Map<String, Expression> attributes = node.getMembers();
-        for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
-            if (!validateEnumConstant(entry.getValue()))
-                return false;
-        }
-        return true;
-    }
-    
-    private boolean validateEnumConstant(Expression exp) {
-        if (exp instanceof PropertyExpression) {
-            PropertyExpression pe = (PropertyExpression) exp;
-            String name = pe.getPropertyAsString();
-            if (pe.getObjectExpression() instanceof ClassExpression && name != null) {
-                ClassExpression ce = (ClassExpression) pe.getObjectExpression();
-                ClassNode type = ce.getType();
-                if (type.isEnum()) {
-                    boolean ok = false;
-                    try {
-                        FieldNode enumField = type.getDeclaredField(name);
-                        ok = enumField != null && enumField.getType().equals(type);
-                    } catch(Exception ex) {
-                        // ignore
-                    }
-                    if(!ok) {
-                        addError("No enum const " + type.getName() + "." + name, pe);
-                        return false;
-                    }
-                }
-            }
-        }
-        return true;
-    }
-
-    private boolean checkIfMandatoryAnnotationValuesPassed(AnnotationNode node) {
-        boolean ok = true;
-        Map attributes = node.getMembers();
-        ClassNode classNode = node.getClassNode();
-        for (MethodNode mn : classNode.getMethods()) {
-            String methodName = mn.getName();
-            // if the annotation attribute has a default, getCode() returns a ReturnStatement with the default value
-            if (mn.getCode() == null && !attributes.containsKey(methodName)) {
-                addError("No explicit/default value found for annotation attribute '" + methodName + "'", node);
-                ok = false;
-            }
-        }
-        return ok;
-    }
-
-    private ClassNode getAttributeType(AnnotationNode node, String attrName) {
-        ClassNode classNode = node.getClassNode();
-        List methods = classNode.getMethods(attrName);
-        // if size is >1, then the method was overwritten or something, we ignore that
-        // if it is an error, we have to test it at another place. But size==0 is
-        // an error, because it means that no such attribute exists.
-        if (methods.isEmpty()) {
-            addError("'" + attrName + "'is not part of the annotation " + classNode, node);
-            return ClassHelper.OBJECT_TYPE;
-        }
-        MethodNode method = (MethodNode) methods.get(0);
-        return method.getReturnType();
-    }
-
-    private static boolean isValidAnnotationClass(ClassNode node) {
-        return node.implementsInterface(ClassHelper.Annotation_TYPE);
-    }
-
-    protected void visitExpression(String attrName, Expression attrExp, ClassNode attrType) {
-        if (attrType.isArray()) {
-            // check needed as @Test(attr = {"elem"}) passes through the parser
-            if (attrExp instanceof ListExpression) {
-                ListExpression le = (ListExpression) attrExp;
-                visitListExpression(attrName, le, attrType.getComponentType());
-            } else if (attrExp instanceof ClosureExpression) {
-                addError("Annotation list attributes must use Groovy notation [el1, el2]", attrExp);
-            } else {
-                // treat like a singleton list as per Java
-                ListExpression listExp = new ListExpression();
-                listExp.addExpression(attrExp);
-                if (annotation != null) {
-                    annotation.setMember(attrName, listExp);
-                }
-                visitExpression(attrName, listExp, attrType);
-            }
-        } else if (ClassHelper.isPrimitiveType(attrType)) {
-            visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.getWrapper(attrType));
-        } else if (ClassHelper.STRING_TYPE.equals(attrType)) {
-            visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.STRING_TYPE);
-        } else if (ClassHelper.CLASS_Type.equals(attrType)) {
-            if (!(attrExp instanceof ClassExpression || attrExp instanceof ClosureExpression)) {
-                addError("Only classes and closures can be used for attribute '" + attrName + "'", attrExp);
-            }
-        } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) {
-            if (attrExp instanceof PropertyExpression) {
-                visitEnumExpression(attrName, (PropertyExpression) attrExp, attrType);
-            } else {
-                addError("Expected enum value for attribute " + attrName, attrExp);
-            }
-        } else if (isValidAnnotationClass(attrType)) {
-            if (attrExp instanceof AnnotationConstantExpression) {
-                visitAnnotationExpression(attrName, (AnnotationConstantExpression) attrExp, attrType);
-            } else {
-                addError("Expected annotation of type '" + attrType.getName() + "' for attribute " + attrName, attrExp);
-            }
-        } else {
-            addError("Unexpected type " + attrType.getName(), attrExp);
-        }
-    }
-
-    public void checkReturnType(ClassNode attrType, ASTNode node) {
-        if (attrType.isArray()) {
-            checkReturnType(attrType.getComponentType(), node);
-        } else if (ClassHelper.isPrimitiveType(attrType)) {
-        } else if (ClassHelper.STRING_TYPE.equals(attrType)) {
-        } else if (ClassHelper.CLASS_Type.equals(attrType)) {
-        } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) {
-        } else if (isValidAnnotationClass(attrType)) {
-        } else {
-            addError("Unexpected return type " + attrType.getName(), node);
-        }
-    }
-
-    private ConstantExpression getConstantExpression(Expression exp, ClassNode attrType) {
-        Expression result = exp;
-        if (!(result instanceof ConstantExpression)) {
-            result = transformInlineConstants(result, attrType);
-        }
-        if (result instanceof ConstantExpression) {
-            return (ConstantExpression) result;
-        }
-        String base = "Expected '" + exp.getText() + "' to be an inline constant of type " + attrType.getName();
-        if (exp instanceof PropertyExpression) {
-            addError(base + " not a property expression", exp);
-        } else if (exp instanceof VariableExpression && ((VariableExpression)exp).getAccessedVariable() instanceof FieldNode) {
-            addError(base + " not a field expression", exp);
-        } else {
-            addError(base, exp);
-        }
-        return ConstantExpression.EMPTY_EXPRESSION;
-    }
-
-    /**
-     * @param attrName   the name
-     * @param expression the expression
-     * @param attrType   the type
-     */
-    protected void visitAnnotationExpression(String attrName, AnnotationConstantExpression expression, ClassNode attrType) {
-        AnnotationNode annotationNode = (AnnotationNode) expression.getValue();
-        AnnotationVisitor visitor = new AnnotationVisitor(this.source, this.errorCollector);
-        // TODO track Deprecated usage and give a warning?
-        visitor.visit(annotationNode);
-    }
-
-    protected void visitListExpression(String attrName, ListExpression listExpr, ClassNode elementType) {
-        for (Expression expression : listExpr.getExpressions()) {
-            visitExpression(attrName, expression, elementType);
-        }
-    }
-
-    protected void visitConstantExpression(String attrName, ConstantExpression constExpr, ClassNode attrType) {
-        ClassNode constType = constExpr.getType();
-        ClassNode wrapperType = ClassHelper.getWrapper(constType);
-        if (!hasCompatibleType(attrType, wrapperType)) {
-            addError("Attribute '" + attrName + "' should have type '" + attrType.getName()
-                    + "'; but found type '" + constType.getName() + "'", constExpr);
-        }
-    }
-
-    private static boolean hasCompatibleType(ClassNode attrType, ClassNode wrapperType) {
-        return wrapperType.isDerivedFrom(ClassHelper.getWrapper(attrType));
-    }
-
-    protected void visitEnumExpression(String attrName, PropertyExpression propExpr, ClassNode attrType) {
-        if (!propExpr.getObjectExpression().getType().isDerivedFrom(attrType)) {
-            addError("Attribute '" + attrName + "' should have type '" + attrType.getName() + "' (Enum), but found "
-                    + propExpr.getObjectExpression().getType().getName(),
-                    propExpr);
-        }
-    }
-
-    protected void addError(String msg) {
-        addError(msg, this.annotation);
-    }
-
-    protected void addError(String msg, ASTNode expr) {
-        this.errorCollector.addErrorAndContinue(
-                new SyntaxErrorMessage(new SyntaxException(msg + " in @" + this.reportClass.getName() + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), this.source)
-        );
-    }
-
-    public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) {
-        if (!isValidAnnotationClass(attrType)) return;
-        if (!(startExp instanceof AnnotationConstantExpression)) {
-            addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp);
-            return;
-        }
-        AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp;
-        AnnotationNode annotationNode = (AnnotationNode) ace.getValue();
-        if (annotationNode.getClassNode().equals(searchClass)) {
-            addError("Circular reference discovered in " + searchClass.getName(), startExp);
-            return;
-        }
-        ClassNode cn = annotationNode.getClassNode();
-        for (MethodNode method : cn.getMethods()) {
-            if (method.getReturnType().equals(searchClass)) {
-                addError("Circular reference discovered in " + cn.getName(), startExp);
-            }
-            ReturnStatement code = (ReturnStatement) method.getCode();
-            if (code == null) continue;
-            checkCircularReference(searchClass, method.getReturnType(), code.getExpression());
-        }
-    }
-
-}
+/*
+ *  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.classgen;
+
+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.FieldNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.ClosureExpression;
+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.PropertyExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.codehaus.groovy.ast.stmt.ReturnStatement;
+import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.syntax.SyntaxException;
+import org.codehaus.groovy.vmplugin.VMPluginFactory;
+
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.groovy.ast.tools.ExpressionUtils.transformInlineConstants;
+
+/**
+ * An Annotation visitor responsible for:
+ * <ul>
+ * <li>reading annotation metadata (@Retention, @Target, attribute types)</li>
+ * <li>verify that an <code>AnnotationNode</code> conforms to annotation meta</li>
+ * <li>enhancing an <code>AnnotationNode</code> AST to reflect real annotation meta</li>
+ * </ul>
+ */
+public class AnnotationVisitor {
+    private final SourceUnit source;
+    private final ErrorCollector errorCollector;
+    private AnnotationNode annotation;
+    private ClassNode reportClass;
+
+    public AnnotationVisitor(SourceUnit source, ErrorCollector errorCollector) {
+        this.source = source;
+        this.errorCollector = errorCollector;
+    }
+
+    public void setReportClass(ClassNode cn) {
+        reportClass = cn;
+    }
+
+    public AnnotationNode visit(AnnotationNode node) {
+        this.annotation = node;
+        this.reportClass = node.getClassNode();
+
+        if (!isValidAnnotationClass(node.getClassNode())) {
+            addError("class " + node.getClassNode().getName() + " is not an annotation");
+            return node;
+        }
+
+        // check if values have been passed for all annotation attributes that don't have defaults
+        if (!checkIfMandatoryAnnotationValuesPassed(node)) {
+            return node;
+        }
+
+        // if enum constants have been used, check if they are all valid
+        if (!checkIfValidEnumConstsAreUsed(node)) {
+            return node;
+        }
+        
+        Map<String, Expression> attributes = node.getMembers();
+        for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
+            String attrName = entry.getKey();
+            ClassNode attrType = getAttributeType(node, attrName);
+            Expression attrExpr = transformInlineConstants(entry.getValue(), attrType);
+            entry.setValue(attrExpr);
+            visitExpression(attrName, attrExpr, attrType);
+        }
+        VMPluginFactory.getPlugin().configureAnnotation(node);
+        return this.annotation;
+    }
+    
+    private boolean checkIfValidEnumConstsAreUsed(AnnotationNode node) {
+        Map<String, Expression> attributes = node.getMembers();
+        for (Map.Entry<String, Expression> entry : attributes.entrySet()) {
+            if (!validateEnumConstant(entry.getValue()))
+                return false;
+        }
+        return true;
+    }
+    
+    private boolean validateEnumConstant(Expression exp) {
+        if (exp instanceof PropertyExpression) {
+            PropertyExpression pe = (PropertyExpression) exp;
+            String name = pe.getPropertyAsString();
+            if (pe.getObjectExpression() instanceof ClassExpression && name != null) {
+                ClassExpression ce = (ClassExpression) pe.getObjectExpression();
+                ClassNode type = ce.getType();
+                if (type.isEnum()) {
+                    boolean ok = false;
+                    try {
+                        FieldNode enumField = type.getDeclaredField(name);
+                        ok = enumField != null && enumField.getType().equals(type);
+                    } catch(Exception ex) {
+                        // ignore
+                    }
+                    if(!ok) {
+                        addError("No enum const " + type.getName() + "." + name, pe);
+                        return false;
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    private boolean checkIfMandatoryAnnotationValuesPassed(AnnotationNode node) {
+        boolean ok = true;
+        Map attributes = node.getMembers();
+        ClassNode classNode = node.getClassNode();
+        for (MethodNode mn : classNode.getMethods()) {
+            String methodName = mn.getName();
+            // if the annotation attribute has a default, getCode() returns a ReturnStatement with the default value
+            if (mn.getCode() == null && !attributes.containsKey(methodName)) {
+                addError("No explicit/default value found for annotation attribute '" + methodName + "'", node);
+                ok = false;
+            }
+        }
+        return ok;
+    }
+
+    private ClassNode getAttributeType(AnnotationNode node, String attrName) {
+        ClassNode classNode = node.getClassNode();
+        List methods = classNode.getMethods(attrName);
+        // if size is >1, then the method was overwritten or something, we ignore that
+        // if it is an error, we have to test it at another place. But size==0 is
+        // an error, because it means that no such attribute exists.
+        if (methods.isEmpty()) {
+            addError("'" + attrName + "'is not part of the annotation " + classNode, node);
+            return ClassHelper.OBJECT_TYPE;
+        }
+        MethodNode method = (MethodNode) methods.get(0);
+        return method.getReturnType();
+    }
+
+    private static boolean isValidAnnotationClass(ClassNode node) {
+        return node.implementsInterface(ClassHelper.Annotation_TYPE);
+    }
+
+    protected void visitExpression(String attrName, Expression attrExp, ClassNode attrType) {
+        if (attrType.isArray()) {
+            // check needed as @Test(attr = {"elem"}) passes through the parser
+            if (attrExp instanceof ListExpression) {
+                ListExpression le = (ListExpression) attrExp;
+                visitListExpression(attrName, le, attrType.getComponentType());
+            } else if (attrExp instanceof ClosureExpression) {
+                addError("Annotation list attributes must use Groovy notation [el1, el2]", attrExp);
+            } else {
+                // treat like a singleton list as per Java
+                ListExpression listExp = new ListExpression();
+                listExp.addExpression(attrExp);
+                if (annotation != null) {
+                    annotation.setMember(attrName, listExp);
+                }
+                visitExpression(attrName, listExp, attrType);
+            }
+        } else if (ClassHelper.isPrimitiveType(attrType)) {
+            visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.getWrapper(attrType));
+        } else if (ClassHelper.STRING_TYPE.equals(attrType)) {
+            visitConstantExpression(attrName, getConstantExpression(attrExp, attrType), ClassHelper.STRING_TYPE);
+        } else if (ClassHelper.CLASS_Type.equals(attrType)) {
+            if (!(attrExp instanceof ClassExpression || attrExp instanceof ClosureExpression)) {
+                addError("Only classes and closures can be used for attribute '" + attrName + "'", attrExp);
+            }
+        } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) {
+            if (attrExp instanceof PropertyExpression) {
+                visitEnumExpression(attrName, (PropertyExpression) attrExp, attrType);
+            } else {
+                addError("Expected enum value for attribute " + attrName, attrExp);
+            }
+        } else if (isValidAnnotationClass(attrType)) {
+            if (attrExp instanceof AnnotationConstantExpression) {
+                visitAnnotationExpression(attrName, (AnnotationConstantExpression) attrExp, attrType);
+            } else {
+                addError("Expected annotation of type '" + attrType.getName() + "' for attribute " + attrName, attrExp);
+            }
+        } else {
+            addError("Unexpected type " + attrType.getName(), attrExp);
+        }
+    }
+
+    public void checkReturnType(ClassNode attrType, ASTNode node) {
+        if (attrType.isArray()) {
+            checkReturnType(attrType.getComponentType(), node);
+        } else if (ClassHelper.isPrimitiveType(attrType)) {
+        } else if (ClassHelper.STRING_TYPE.equals(attrType)) {
+        } else if (ClassHelper.CLASS_Type.equals(attrType)) {
+        } else if (attrType.isDerivedFrom(ClassHelper.Enum_Type)) {
+        } else if (isValidAnnotationClass(attrType)) {
+        } else {
+            addError("Unexpected return type " + attrType.getName(), node);
+        }
+    }
+
+    private ConstantExpression getConstantExpression(Expression exp, ClassNode attrType) {
+        Expression result = exp;
+        if (!(result instanceof ConstantExpression)) {
+            result = transformInlineConstants(result, attrType);
+        }
+        if (result instanceof ConstantExpression) {
+            return (ConstantExpression) result;
+        }
+        String base = "Expected '" + exp.getText() + "' to be an inline constant of type " + attrType.getName();
+        if (exp instanceof PropertyExpression) {
+            addError(base + " not a property expression", exp);
+        } else if (exp instanceof VariableExpression && ((VariableExpression)exp).getAccessedVariable() instanceof FieldNode) {
+            addError(base + " not a field expression", exp);
+        } else {
+            addError(base, exp);
+        }
+        return ConstantExpression.EMPTY_EXPRESSION;
+    }
+
+    /**
+     * @param attrName   the name
+     * @param expression the expression
+     * @param attrType   the type
+     */
+    protected void visitAnnotationExpression(String attrName, AnnotationConstantExpression expression, ClassNode attrType) {
+        AnnotationNode annotationNode = (AnnotationNode) expression.getValue();
+        AnnotationVisitor visitor = new AnnotationVisitor(this.source, this.errorCollector);
+        // TODO track Deprecated usage and give a warning?
+        visitor.visit(annotationNode);
+    }
+
+    protected void visitListExpression(String attrName, ListExpression listExpr, ClassNode elementType) {
+        for (Expression expression : listExpr.getExpressions()) {
+            visitExpression(attrName, expression, elementType);
+        }
+    }
+
+    protected void visitConstantExpression(String attrName, ConstantExpression constExpr, ClassNode attrType) {
+        ClassNode constType = constExpr.getType();
+        ClassNode wrapperType = ClassHelper.getWrapper(constType);
+        if (!hasCompatibleType(attrType, wrapperType)) {
+            addError("Attribute '" + attrName + "' should have type '" + attrType.getName()
+                    + "'; but found type '" + constType.getName() + "'", constExpr);
+        }
+    }
+
+    private static boolean hasCompatibleType(ClassNode attrType, ClassNode wrapperType) {
+        return wrapperType.isDerivedFrom(ClassHelper.getWrapper(attrType));
+    }
+
+    protected void visitEnumExpression(String attrName, PropertyExpression propExpr, ClassNode attrType) {
+        if (!propExpr.getObjectExpression().getType().isDerivedFrom(attrType)) {
+            addError("Attribute '" + attrName + "' should have type '" + attrType.getName() + "' (Enum), but found "
+                    + propExpr.getObjectExpression().getType().getName(),
+                    propExpr);
+        }
+    }
+
+    protected void addError(String msg) {
+        addError(msg, this.annotation);
+    }
+
+    protected void addError(String msg, ASTNode expr) {
+        this.errorCollector.addErrorAndContinue(
+                new SyntaxErrorMessage(new SyntaxException(msg + " in @" + this.reportClass.getName() + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), this.source)
+        );
+    }
+
+    public void checkCircularReference(ClassNode searchClass, ClassNode attrType, Expression startExp) {
+        if (!isValidAnnotationClass(attrType)) return;
+        if (!(startExp instanceof AnnotationConstantExpression)) {
+            addError("Found '" + startExp.getText() + "' when expecting an Annotation Constant", startExp);
+            return;
+        }
+        AnnotationConstantExpression ace = (AnnotationConstantExpression) startExp;
+        AnnotationNode annotationNode = (AnnotationNode) ace.getValue();
+        if (annotationNode.getClassNode().equals(searchClass)) {
+            addError("Circular reference discovered in " + searchClass.getName(), startExp);
+            return;
+        }
+        ClassNode cn = annotationNode.getClassNode();
+        for (MethodNode method : cn.getMethods()) {
+            if (method.getReturnType().equals(searchClass)) {
+                addError("Circular reference discovered in " + cn.getName(), startExp);
+            }
+            ReturnStatement code = (ReturnStatement) method.getCode();
+            if (code == null) continue;
+            checkCircularReference(searchClass, method.getReturnType(), code.getExpression());
+        }
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/classgen/BytecodeSequence.java b/src/main/java/org/codehaus/groovy/classgen/BytecodeSequence.java
index c5a6645..7da3c4d 100644
--- a/src/main/java/org/codehaus/groovy/classgen/BytecodeSequence.java
+++ b/src/main/java/org/codehaus/groovy/classgen/BytecodeSequence.java
@@ -1,81 +1,81 @@
-/*
- *  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.classgen;
-
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.GroovyCodeVisitor;
-import org.codehaus.groovy.ast.stmt.Statement;
-
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * This class represents a sequence of BytecodeInstructions
- * or ASTNodes. The evaluation is depending on the type of 
- * the visitor.
- * 
- * @see BytecodeInstruction
- * @see ASTNode
- */
-
-public class BytecodeSequence extends Statement {
-    private final List<BytecodeInstruction> instructions;
-
-    public BytecodeSequence(List instructions) {
-        this.instructions = instructions;
-    }
-    
-    public BytecodeSequence(BytecodeInstruction instruction) {
-        this.instructions = new ArrayList(1);
-        this.instructions.add(instruction);
-    }
-
-    /**
-     * Delegates to the visit method used for this class.
-     * If the visitor is a ClassGenerator, then 
-     * {@link ClassGenerator#visitBytecodeSequence(BytecodeSequence)}
-     * is called with this instance. If the visitor is no 
-     * ClassGenerator, then this method will call visit on
-     * each ASTNode element sorted by this class. If one
-     * element is a BytecodeInstruction, then it will be skipped
-     * as it is no ASTNode. 
-     * 
-     * @param visitor the visitor
-     * @see ClassGenerator
-     */
-    public void visit(GroovyCodeVisitor visitor) {
-        if (visitor instanceof ClassGenerator) {
-            ClassGenerator gen = (ClassGenerator) visitor;
-            gen.visitBytecodeSequence(this);
-            return;
-        }
-        for (Iterator iterator = instructions.iterator(); iterator.hasNext();) {
-            Object part = (Object) iterator.next();
-            if (part instanceof ASTNode) {
-                ((ASTNode)part).visit(visitor);
-            }
-        }
-    }
-
-    public List getInstructions() {
-        return instructions;
-    }
-
-}
+/*
+ *  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.classgen;
+
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.GroovyCodeVisitor;
+import org.codehaus.groovy.ast.stmt.Statement;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * This class represents a sequence of BytecodeInstructions
+ * or ASTNodes. The evaluation is depending on the type of 
+ * the visitor.
+ * 
+ * @see BytecodeInstruction
+ * @see ASTNode
+ */
+
+public class BytecodeSequence extends Statement {
+    private final List<BytecodeInstruction> instructions;
+
+    public BytecodeSequence(List instructions) {
+        this.instructions = instructions;
+    }
+    
+    public BytecodeSequence(BytecodeInstruction instruction) {
+        this.instructions = new ArrayList(1);
+        this.instructions.add(instruction);
+    }
+
+    /**
+     * Delegates to the visit method used for this class.
+     * If the visitor is a ClassGenerator, then 
+     * {@link ClassGenerator#visitBytecodeSequence(BytecodeSequence)}
+     * is called with this instance. If the visitor is no 
+     * ClassGenerator, then this method will call visit on
+     * each ASTNode element sorted by this class. If one
+     * element is a BytecodeInstruction, then it will be skipped
+     * as it is no ASTNode. 
+     * 
+     * @param visitor the visitor
+     * @see ClassGenerator
+     */
+    public void visit(GroovyCodeVisitor visitor) {
+        if (visitor instanceof ClassGenerator) {
+            ClassGenerator gen = (ClassGenerator) visitor;
+            gen.visitBytecodeSequence(this);
+            return;
+        }
+        for (Iterator iterator = instructions.iterator(); iterator.hasNext();) {
+            Object part = (Object) iterator.next();
+            if (part instanceof ASTNode) {
+                ((ASTNode)part).visit(visitor);
+            }
+        }
+    }
+
+    public List getInstructions() {
+        return instructions;
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
index 8b7ed89..96849ac 100644
--- a/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
+++ b/src/main/java/org/codehaus/groovy/classgen/ExtendedVerifier.java
@@ -1,341 +1,341 @@
-/*
- *  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.classgen;
-
-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.ConstructorNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.GenericsType;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.PackageNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-import org.codehaus.groovy.ast.expr.DeclarationExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.ListExpression;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.ParameterUtils;
-import org.codehaus.groovy.control.AnnotationConstantsVisitor;
-import org.codehaus.groovy.control.CompilerConfiguration;
-import org.codehaus.groovy.control.ErrorCollector;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.objectweb.asm.Opcodes;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-
-import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
-import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
-import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
-
-/**
- * A specialized Groovy AST visitor meant to perform additional verifications upon the
- * current AST. Currently it does checks on annotated nodes and annotations itself.
- * <p>
- * Current limitations:
- * - annotations on local variables are not supported
- */
-public class ExtendedVerifier extends ClassCodeVisitorSupport {
-    public static final String JVM_ERROR_MESSAGE = "Please make sure you are running on a JVM >= 1.5";
-
-    private final SourceUnit source;
-    private ClassNode currentClass;
-
-    public ExtendedVerifier(SourceUnit sourceUnit) {
-        this.source = sourceUnit;
-    }
-
-    public void visitClass(ClassNode node) {
-        AnnotationConstantsVisitor acv = new AnnotationConstantsVisitor();
-        acv.visitClass(node, this.source);
-        this.currentClass = node;
-        if (node.isAnnotationDefinition()) {
-            visitAnnotations(node, AnnotationNode.ANNOTATION_TARGET);
-        } else {
-            visitAnnotations(node, AnnotationNode.TYPE_TARGET);
-        }
-        PackageNode packageNode = node.getPackage();
-        if (packageNode != null) {
-            visitAnnotations(packageNode, AnnotationNode.PACKAGE_TARGET);
-        }
-        node.visitContents(this);
-    }
-
-    public void visitField(FieldNode node) {
-        visitAnnotations(node, AnnotationNode.FIELD_TARGET);
-    }
-
-    @Override
-    public void visitDeclarationExpression(DeclarationExpression expression) {
-        visitAnnotations(expression, AnnotationNode.LOCAL_VARIABLE_TARGET);
-    }
-
-    public void visitConstructor(ConstructorNode node) {
-        visitConstructorOrMethod(node, AnnotationNode.CONSTRUCTOR_TARGET);
-    }
-
-    public void visitMethod(MethodNode node) {
-        visitConstructorOrMethod(node, AnnotationNode.METHOD_TARGET);
-    }
-
-    private void visitConstructorOrMethod(MethodNode node, int methodTarget) {
-        visitAnnotations(node, methodTarget);
-        for (int i = 0; i < node.getParameters().length; i++) {
-            Parameter parameter = node.getParameters()[i];
-            visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET);
-        }
-
-        if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) {
-            ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration());
-            AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector);
-            visitor.setReportClass(currentClass);
-            visitor.checkReturnType(node.getReturnType(), node);
-            if (node.getParameters().length > 0) {
-                addError("Annotation members may not have parameters.", node.getParameters()[0]);
-            }
-            if (node.getExceptions().length > 0) {
-                addError("Annotation members may not have a throws clause.", node.getExceptions()[0]);
-            }
-            ReturnStatement code = (ReturnStatement) node.getCode();
-            if (code != null) {
-                visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType());
-                visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression());
-            }
-            this.source.getErrorCollector().addCollectorContents(errorCollector);
-        }
-        Statement code = node.getCode();
-        if (code != null) {
-            code.visit(this);
-        }
-
-    }
-
-    public void visitProperty(PropertyNode node) {
-    }
-
-    protected void visitAnnotations(AnnotatedNode node, int target) {
-        if (node.getAnnotations().isEmpty()) {
-            return;
-        }
-        this.currentClass.setAnnotated(true);
-        if (!isAnnotationCompatible()) {
-            addError("Annotations are not supported in the current runtime. " + JVM_ERROR_MESSAGE, node);
-            return;
-        }
-        Map<String, List<AnnotationNode>> runtimeAnnotations = new LinkedHashMap<String, List<AnnotationNode>>();
-        for (AnnotationNode unvisited : node.getAnnotations()) {
-            AnnotationNode visited = visitAnnotation(unvisited);
-            String name = visited.getClassNode().getName();
-            if (visited.hasRuntimeRetention()) {
-                List<AnnotationNode> seen = runtimeAnnotations.get(name);
-                if (seen == null) {
-                    seen = new ArrayList<AnnotationNode>();
-                }
-                seen.add(visited);
-                runtimeAnnotations.put(name, seen);
-            }
-            boolean isTargetAnnotation = name.equals("java.lang.annotation.Target");
-
-            // Check if the annotation target is correct, unless it's the target annotating an annotation definition
-            // defining on which target elements the annotation applies
-            if (!isTargetAnnotation && !visited.isTargetAllowed(target)) {
-                addError("Annotation @" + name + " is not allowed on element "
-                        + AnnotationNode.targetToName(target), visited);
-            }
-            visitDeprecation(node, visited);
-            visitOverride(node, visited);
-        }
-        checkForDuplicateAnnotations(node, runtimeAnnotations);
-    }
-
-    private void checkForDuplicateAnnotations(AnnotatedNode node, Map<String, List<AnnotationNode>> runtimeAnnotations) {
-        for (Map.Entry<String, List<AnnotationNode>> next : runtimeAnnotations.entrySet()) {
-            if (next.getValue().size() > 1) {
-                ClassNode repeatable = null;
-                AnnotationNode repeatee = next.getValue().get(0);
-                List<AnnotationNode> repeateeAnnotations = repeatee.getClassNode().getAnnotations();
-                for (AnnotationNode anno : repeateeAnnotations) {
-                    ClassNode annoClassNode = anno.getClassNode();
-                    if (annoClassNode.getName().equals("java.lang.annotation.Repeatable")) {
-                        Expression value = anno.getMember("value");
-                        if (value instanceof ClassExpression) {
-                            ClassExpression ce = (ClassExpression) value;
-                            if (ce.getType() != null && ce.getType().isAnnotationDefinition()) {
-                                repeatable = ce.getType();
-                                break;
-                            }
-                        }
-                    }
-                }
-                if (repeatable != null) {
-                    AnnotationNode collector = new AnnotationNode(repeatable);
-                    collector.setRuntimeRetention(true); // checked earlier
-                    List<Expression> annos = new ArrayList<Expression>();
-                    for (AnnotationNode an : next.getValue()) {
-                        annos.add(new AnnotationConstantExpression(an));
-                    }
-                    collector.addMember("value", new ListExpression(annos));
-                    node.addAnnotation(collector);
-                    node.getAnnotations().removeAll(next.getValue());
-                }
-            }
-        }
-    }
-
-    private static void visitDeprecation(AnnotatedNode node, AnnotationNode visited) {
-        if (visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.Deprecated")) {
-            if (node instanceof MethodNode) {
-                MethodNode mn = (MethodNode) node;
-                mn.setModifiers(mn.getModifiers() | Opcodes.ACC_DEPRECATED);
-            } else if (node instanceof FieldNode) {
-                FieldNode fn = (FieldNode) node;
-                fn.setModifiers(fn.getModifiers() | Opcodes.ACC_DEPRECATED);
-            } else if (node instanceof ClassNode) {
-                ClassNode cn = (ClassNode) node;
-                cn.setModifiers(cn.getModifiers() | Opcodes.ACC_DEPRECATED);
-            }
-        }
-    }
-
-    // TODO GROOVY-5011 handle case of @Override on a property
-    private void visitOverride(AnnotatedNode node, AnnotationNode visited) {
-        ClassNode annotationClassNode = visited.getClassNode();
-        if (annotationClassNode.isResolved() && annotationClassNode.getName().equals("java.lang.Override")) {
-            if (node instanceof MethodNode && !Boolean.TRUE.equals(node.getNodeMetaData(Verifier.DEFAULT_PARAMETER_GENERATED))) {
-                boolean override = false;
-                MethodNode origMethod = (MethodNode) node;
-                ClassNode cNode = origMethod.getDeclaringClass();
-                if (origMethod.hasDefaultValue()) {
-                    List<MethodNode> variants = cNode.getDeclaredMethods(origMethod.getName());
-                    for (MethodNode m : variants) {
-                        if (m.getAnnotations().contains(visited) && isOverrideMethod(m)) {
-                            override = true;
-                            break;
-                        }
-                    }
-                } else {
-                    override = isOverrideMethod(origMethod);
-                }
-
-                if (!override) {
-                    addError("Method '" + origMethod.getName() + "' from class '" + cNode.getName() + "' does not override " +
-                            "method from its superclass or interfaces but is annotated with @Override.", visited);
-                }
-            }
-        }
-    }
-
-    private static boolean isOverrideMethod(MethodNode method) {
-        ClassNode cNode = method.getDeclaringClass();
-        ClassNode next = cNode;
-        outer:
-        while (next != null) {
-            Map genericsSpec = createGenericsSpec(next);
-            MethodNode mn = correctToGenericsSpec(genericsSpec, method);
-            if (next != cNode) {
-                ClassNode correctedNext = correctToGenericsSpecRecurse(genericsSpec, next);
-                MethodNode found = getDeclaredMethodCorrected(genericsSpec, mn, correctedNext);
-                if (found != null) break;
-            }
-            List<ClassNode> ifaces = new ArrayList<ClassNode>(Arrays.asList(next.getInterfaces()));
-            Map updatedGenericsSpec = new HashMap(genericsSpec);
-            while (!ifaces.isEmpty()) {
-                ClassNode origInterface = ifaces.remove(0);
-                if (!origInterface.equals(ClassHelper.OBJECT_TYPE)) {
-                    updatedGenericsSpec = createGenericsSpec(origInterface, updatedGenericsSpec);
-                    ClassNode iNode = correctToGenericsSpecRecurse(updatedGenericsSpec, origInterface);
-                    MethodNode found2 = getDeclaredMethodCorrected(updatedGenericsSpec, mn, iNode);
-                    if (found2 != null) break outer;
-                    ifaces.addAll(Arrays.asList(iNode.getInterfaces()));
-                }
-            }
-            ClassNode superClass = next.getUnresolvedSuperClass();
-            if (superClass != null) {
-                next =  correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
-            } else {
-                next = null;
-            }
-        }
-        return next != null;
-    }
-
-    private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
-        for (MethodNode orig :  correctedNext.getDeclaredMethods(mn.getName())) {
-            MethodNode method = correctToGenericsSpec(genericsSpec, orig);
-            if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
-                return method;
-            }
-        }
-        return null;
-    }
-
-    /**
-     * Resolve metadata and details of the annotation.
-     *
-     * @param unvisited the node to visit
-     * @return the visited node
-     */
-    private AnnotationNode visitAnnotation(AnnotationNode unvisited) {
-        ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration());
-        AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector);
-        AnnotationNode visited = visitor.visit(unvisited);
-        this.source.getErrorCollector().addCollectorContents(errorCollector);
-        return visited;
-    }
-
-    /**
-     * Check if the current runtime allows Annotation usage.
-     *
-     * @return true if running on a 1.5+ runtime
-     */
-    protected boolean isAnnotationCompatible() {
-        return CompilerConfiguration.isPostJDK5(this.source.getConfiguration().getTargetBytecode());
-    }
-
-    public void addError(String msg, ASTNode expr) {
-        this.source.getErrorCollector().addErrorAndContinue(
-                new SyntaxErrorMessage(
-                        new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), this.source)
-        );
-    }
-
-    @Override
-    protected SourceUnit getSourceUnit() {
-        return source;
-    }
-
-    // TODO use it or lose it
-    public void visitGenericType(GenericsType genericsType) {
-
-    }
-}
+/*
+ *  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.classgen;
+
+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.ConstructorNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.GenericsType;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.PackageNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.expr.AnnotationConstantExpression;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+import org.codehaus.groovy.ast.expr.DeclarationExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.ListExpression;
+import org.codehaus.groovy.ast.stmt.ReturnStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.ast.tools.ParameterUtils;
+import org.codehaus.groovy.control.AnnotationConstantsVisitor;
+import org.codehaus.groovy.control.CompilerConfiguration;
+import org.codehaus.groovy.control.ErrorCollector;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.syntax.SyntaxException;
+import org.objectweb.asm.Opcodes;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpec;
+import static org.codehaus.groovy.ast.tools.GenericsUtils.correctToGenericsSpecRecurse;
+import static org.codehaus.groovy.ast.tools.GenericsUtils.createGenericsSpec;
+
+/**
+ * A specialized Groovy AST visitor meant to perform additional verifications upon the
+ * current AST. Currently it does checks on annotated nodes and annotations itself.
+ * <p>
+ * Current limitations:
+ * - annotations on local variables are not supported
+ */
+public class ExtendedVerifier extends ClassCodeVisitorSupport {
+    public static final String JVM_ERROR_MESSAGE = "Please make sure you are running on a JVM >= 1.5";
+
+    private final SourceUnit source;
+    private ClassNode currentClass;
+
+    public ExtendedVerifier(SourceUnit sourceUnit) {
+        this.source = sourceUnit;
+    }
+
+    public void visitClass(ClassNode node) {
+        AnnotationConstantsVisitor acv = new AnnotationConstantsVisitor();
+        acv.visitClass(node, this.source);
+        this.currentClass = node;
+        if (node.isAnnotationDefinition()) {
+            visitAnnotations(node, AnnotationNode.ANNOTATION_TARGET);
+        } else {
+            visitAnnotations(node, AnnotationNode.TYPE_TARGET);
+        }
+        PackageNode packageNode = node.getPackage();
+        if (packageNode != null) {
+            visitAnnotations(packageNode, AnnotationNode.PACKAGE_TARGET);
+        }
+        node.visitContents(this);
+    }
+
+    public void visitField(FieldNode node) {
+        visitAnnotations(node, AnnotationNode.FIELD_TARGET);
+    }
+
+    @Override
+    public void visitDeclarationExpression(DeclarationExpression expression) {
+        visitAnnotations(expression, AnnotationNode.LOCAL_VARIABLE_TARGET);
+    }
+
+    public void visitConstructor(ConstructorNode node) {
+        visitConstructorOrMethod(node, AnnotationNode.CONSTRUCTOR_TARGET);
+    }
+
+    public void visitMethod(MethodNode node) {
+        visitConstructorOrMethod(node, AnnotationNode.METHOD_TARGET);
+    }
+
+    private void visitConstructorOrMethod(MethodNode node, int methodTarget) {
+        visitAnnotations(node, methodTarget);
+        for (int i = 0; i < node.getParameters().length; i++) {
+            Parameter parameter = node.getParameters()[i];
+            visitAnnotations(parameter, AnnotationNode.PARAMETER_TARGET);
+        }
+
+        if (this.currentClass.isAnnotationDefinition() && !node.isStaticConstructor()) {
+            ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration());
+            AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector);
+            visitor.setReportClass(currentClass);
+            visitor.checkReturnType(node.getReturnType(), node);
+            if (node.getParameters().length > 0) {
+                addError("Annotation members may not have parameters.", node.getParameters()[0]);
+            }
+            if (node.getExceptions().length > 0) {
+                addError("Annotation members may not have a throws clause.", node.getExceptions()[0]);
+            }
+            ReturnStatement code = (ReturnStatement) node.getCode();
+            if (code != null) {
+                visitor.visitExpression(node.getName(), code.getExpression(), node.getReturnType());
+                visitor.checkCircularReference(currentClass, node.getReturnType(), code.getExpression());
+            }
+            this.source.getErrorCollector().addCollectorContents(errorCollector);
+        }
+        Statement code = node.getCode();
+        if (code != null) {
+            code.visit(this);
+        }
+
+    }
+
+    public void visitProperty(PropertyNode node) {
+    }
+
+    protected void visitAnnotations(AnnotatedNode node, int target) {
+        if (node.getAnnotations().isEmpty()) {
+            return;
+        }
+        this.currentClass.setAnnotated(true);
+        if (!isAnnotationCompatible()) {
+            addError("Annotations are not supported in the current runtime. " + JVM_ERROR_MESSAGE, node);
+            return;
+        }
+        Map<String, List<AnnotationNode>> runtimeAnnotations = new LinkedHashMap<String, List<AnnotationNode>>();
+        for (AnnotationNode unvisited : node.getAnnotations()) {
+            AnnotationNode visited = visitAnnotation(unvisited);
+            String name = visited.getClassNode().getName();
+            if (visited.hasRuntimeRetention()) {
+                List<AnnotationNode> seen = runtimeAnnotations.get(name);
+                if (seen == null) {
+                    seen = new ArrayList<AnnotationNode>();
+                }
+                seen.add(visited);
+                runtimeAnnotations.put(name, seen);
+            }
+            boolean isTargetAnnotation = name.equals("java.lang.annotation.Target");
+
+            // Check if the annotation target is correct, unless it's the target annotating an annotation definition
+            // defining on which target elements the annotation applies
+            if (!isTargetAnnotation && !visited.isTargetAllowed(target)) {
+                addError("Annotation @" + name + " is not allowed on element "
+                        + AnnotationNode.targetToName(target), visited);
+            }
+            visitDeprecation(node, visited);
+            visitOverride(node, visited);
+        }
+        checkForDuplicateAnnotations(node, runtimeAnnotations);
+    }
+
+    private void checkForDuplicateAnnotations(AnnotatedNode node, Map<String, List<AnnotationNode>> runtimeAnnotations) {
+        for (Map.Entry<String, List<AnnotationNode>> next : runtimeAnnotations.entrySet()) {
+            if (next.getValue().size() > 1) {
+                ClassNode repeatable = null;
+                AnnotationNode repeatee = next.getValue().get(0);
+                List<AnnotationNode> repeateeAnnotations = repeatee.getClassNode().getAnnotations();
+                for (AnnotationNode anno : repeateeAnnotations) {
+                    ClassNode annoClassNode = anno.getClassNode();
+                    if (annoClassNode.getName().equals("java.lang.annotation.Repeatable")) {
+                        Expression value = anno.getMember("value");
+                        if (value instanceof ClassExpression) {
+                            ClassExpression ce = (ClassExpression) value;
+                            if (ce.getType() != null && ce.getType().isAnnotationDefinition()) {
+                                repeatable = ce.getType();
+                                break;
+                            }
+                        }
+                    }
+                }
+                if (repeatable != null) {
+                    AnnotationNode collector = new AnnotationNode(repeatable);
+                    collector.setRuntimeRetention(true); // checked earlier
+                    List<Expression> annos = new ArrayList<Expression>();
+                    for (AnnotationNode an : next.getValue()) {
+                        annos.add(new AnnotationConstantExpression(an));
+                    }
+                    collector.addMember("value", new ListExpression(annos));
+                    node.addAnnotation(collector);
+                    node.getAnnotations().removeAll(next.getValue());
+                }
+            }
+        }
+    }
+
+    private static void visitDeprecation(AnnotatedNode node, AnnotationNode visited) {
+        if (visited.getClassNode().isResolved() && visited.getClassNode().getName().equals("java.lang.Deprecated")) {
+            if (node instanceof MethodNode) {
+                MethodNode mn = (MethodNode) node;
+                mn.setModifiers(mn.getModifiers() | Opcodes.ACC_DEPRECATED);
+            } else if (node instanceof FieldNode) {
+                FieldNode fn = (FieldNode) node;
+                fn.setModifiers(fn.getModifiers() | Opcodes.ACC_DEPRECATED);
+            } else if (node instanceof ClassNode) {
+                ClassNode cn = (ClassNode) node;
+                cn.setModifiers(cn.getModifiers() | Opcodes.ACC_DEPRECATED);
+            }
+        }
+    }
+
+    // TODO GROOVY-5011 handle case of @Override on a property
+    private void visitOverride(AnnotatedNode node, AnnotationNode visited) {
+        ClassNode annotationClassNode = visited.getClassNode();
+        if (annotationClassNode.isResolved() && annotationClassNode.getName().equals("java.lang.Override")) {
+            if (node instanceof MethodNode && !Boolean.TRUE.equals(node.getNodeMetaData(Verifier.DEFAULT_PARAMETER_GENERATED))) {
+                boolean override = false;
+                MethodNode origMethod = (MethodNode) node;
+                ClassNode cNode = origMethod.getDeclaringClass();
+                if (origMethod.hasDefaultValue()) {
+                    List<MethodNode> variants = cNode.getDeclaredMethods(origMethod.getName());
+                    for (MethodNode m : variants) {
+                        if (m.getAnnotations().contains(visited) && isOverrideMethod(m)) {
+                            override = true;
+                            break;
+                        }
+                    }
+                } else {
+                    override = isOverrideMethod(origMethod);
+                }
+
+                if (!override) {
+                    addError("Method '" + origMethod.getName() + "' from class '" + cNode.getName() + "' does not override " +
+                            "method from its superclass or interfaces but is annotated with @Override.", visited);
+                }
+            }
+        }
+    }
+
+    private static boolean isOverrideMethod(MethodNode method) {
+        ClassNode cNode = method.getDeclaringClass();
+        ClassNode next = cNode;
+        outer:
+        while (next != null) {
+            Map genericsSpec = createGenericsSpec(next);
+            MethodNode mn = correctToGenericsSpec(genericsSpec, method);
+            if (next != cNode) {
+                ClassNode correctedNext = correctToGenericsSpecRecurse(genericsSpec, next);
+                MethodNode found = getDeclaredMethodCorrected(genericsSpec, mn, correctedNext);
+                if (found != null) break;
+            }
+            List<ClassNode> ifaces = new ArrayList<ClassNode>(Arrays.asList(next.getInterfaces()));
+            Map updatedGenericsSpec = new HashMap(genericsSpec);
+            while (!ifaces.isEmpty()) {
+                ClassNode origInterface = ifaces.remove(0);
+                if (!origInterface.equals(ClassHelper.OBJECT_TYPE)) {
+                    updatedGenericsSpec = createGenericsSpec(origInterface, updatedGenericsSpec);
+                    ClassNode iNode = correctToGenericsSpecRecurse(updatedGenericsSpec, origInterface);
+                    MethodNode found2 = getDeclaredMethodCorrected(updatedGenericsSpec, mn, iNode);
+                    if (found2 != null) break outer;
+                    ifaces.addAll(Arrays.asList(iNode.getInterfaces()));
+                }
+            }
+            ClassNode superClass = next.getUnresolvedSuperClass();
+            if (superClass != null) {
+                next =  correctToGenericsSpecRecurse(updatedGenericsSpec, superClass);
+            } else {
+                next = null;
+            }
+        }
+        return next != null;
+    }
+
+    private static MethodNode getDeclaredMethodCorrected(Map genericsSpec, MethodNode mn, ClassNode correctedNext) {
+        for (MethodNode orig :  correctedNext.getDeclaredMethods(mn.getName())) {
+            MethodNode method = correctToGenericsSpec(genericsSpec, orig);
+            if (ParameterUtils.parametersEqual(method.getParameters(), mn.getParameters())) {
+                return method;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Resolve metadata and details of the annotation.
+     *
+     * @param unvisited the node to visit
+     * @return the visited node
+     */
+    private AnnotationNode visitAnnotation(AnnotationNode unvisited) {
+        ErrorCollector errorCollector = new ErrorCollector(this.source.getConfiguration());
+        AnnotationVisitor visitor = new AnnotationVisitor(this.source, errorCollector);
+        AnnotationNode visited = visitor.visit(unvisited);
+        this.source.getErrorCollector().addCollectorContents(errorCollector);
+        return visited;
+    }
+
+    /**
+     * Check if the current runtime allows Annotation usage.
+     *
+     * @return true if running on a 1.5+ runtime
+     */
+    protected boolean isAnnotationCompatible() {
+        return CompilerConfiguration.isPostJDK5(this.source.getConfiguration().getTargetBytecode());
+    }
+
+    public void addError(String msg, ASTNode expr) {
+        this.source.getErrorCollector().addErrorAndContinue(
+                new SyntaxErrorMessage(
+                        new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(), expr.getLastLineNumber(), expr.getLastColumnNumber()), this.source)
+        );
+    }
+
+    @Override
+    protected SourceUnit getSourceUnit() {
+        return source;
+    }
+
+    // TODO use it or lose it
+    public void visitGenericType(GenericsType genericsType) {
+
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
index 0971146..9452768 100644
--- a/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
+++ b/src/main/java/org/codehaus/groovy/classgen/InnerClassVisitorHelper.java
@@ -1,143 +1,143 @@
-/*
- *  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.classgen;
-
-import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.InnerClassNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.VariableScope;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.BinaryExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.FieldExpression;
-import org.codehaus.groovy.ast.expr.GStringExpression;
-import org.codehaus.groovy.ast.expr.MethodCallExpression;
-import org.codehaus.groovy.ast.expr.PropertyExpression;
-import org.codehaus.groovy.ast.expr.SpreadExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.ReturnStatement;
-import org.codehaus.groovy.syntax.Token;
-import org.codehaus.groovy.syntax.Types;
-import org.objectweb.asm.Opcodes;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public abstract class InnerClassVisitorHelper extends ClassCodeVisitorSupport {
-    protected static void setPropertyGetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
-        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
-        gStringStrings.add(new ConstantExpression(""));
-        gStringStrings.add(new ConstantExpression(""));
-        List<Expression> gStringValues = new ArrayList<Expression>();
-        gStringValues.add(new VariableExpression(parameters[0]));
-        block.addStatement(
-                new ReturnStatement(
-                        new PropertyExpression(
-                                thiz,
-                                new GStringExpression("$name", gStringStrings, gStringValues)
-                        )
-                )
-        );
-    }
-
-    protected static void setPropertySetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
-        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
-        gStringStrings.add(new ConstantExpression(""));
-        gStringStrings.add(new ConstantExpression(""));
-        List<Expression> gStringValues = new ArrayList<Expression>();
-        gStringValues.add(new VariableExpression(parameters[0]));
-        block.addStatement(
-                new ExpressionStatement(
-                        new BinaryExpression(
-                                new PropertyExpression(
-                                        thiz,
-                                        new GStringExpression("$name", gStringStrings, gStringValues)
-                                ),
-                                Token.newSymbol(Types.ASSIGN, -1, -1),
-                                new VariableExpression(parameters[1])
-                        )
-                )
-        );
-    }
-
-    protected static void setMethodDispatcherCode(BlockStatement block, Expression thiz, Parameter[] parameters) {
-        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
-        gStringStrings.add(new ConstantExpression(""));
-        gStringStrings.add(new ConstantExpression(""));
-        List<Expression> gStringValues = new ArrayList<Expression>();
-        gStringValues.add(new VariableExpression(parameters[0]));
-        block.addStatement(
-                new ReturnStatement(
-                        new MethodCallExpression(
-                                thiz,
-                                new GStringExpression("$name", gStringStrings, gStringValues),
-                                new ArgumentListExpression(
-                                        new SpreadExpression(new VariableExpression(parameters[1]))
-                                )
-                        )
-                )
-        );
-    }
-
-    protected static boolean isStatic(InnerClassNode node) {
-        VariableScope scope = node.getVariableScope();
-        if (scope != null) return scope.getParent().isInStaticContext();
-        return (node.getModifiers() & Opcodes.ACC_STATIC) != 0;
-    }
-
-    protected static ClassNode getClassNode(ClassNode node, boolean isStatic) {
-        if (isStatic) node = ClassHelper.CLASS_Type;
-        return node;
-    }
-
-    protected static int getObjectDistance(ClassNode node) {
-        int count = 0;
-        while (node != null && node != ClassHelper.OBJECT_TYPE) {
-            count++;
-            node = node.getSuperClass();
-        }
-        return count;
-    }
-
-    protected static void addFieldInit(Parameter p, FieldNode fn, BlockStatement block) {
-        VariableExpression ve = new VariableExpression(p);
-        FieldExpression fe = new FieldExpression(fn);
-        block.addStatement(new ExpressionStatement(
-                new BinaryExpression(fe, Token.newSymbol(Types.ASSIGN, -1, -1), ve)
-        ));
-    }
-
-    protected static boolean shouldHandleImplicitThisForInnerClass(ClassNode cn) {
-        if (cn.isEnum() || cn.isInterface()) return false;
-        if ((cn.getModifiers() & Opcodes.ACC_STATIC) != 0) return false;
-
-        if (!(cn instanceof InnerClassNode)) return false;
-        InnerClassNode innerClass = (InnerClassNode) cn;
-        // scope != null means aic, we don't handle that here
-        if (innerClass.getVariableScope() != null) return false;
-        // static inner classes don't need this$0
-        return (innerClass.getModifiers() & Opcodes.ACC_STATIC) == 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 org.codehaus.groovy.classgen;
+
+import org.codehaus.groovy.ast.ClassCodeVisitorSupport;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.InnerClassNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.VariableScope;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.BinaryExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.FieldExpression;
+import org.codehaus.groovy.ast.expr.GStringExpression;
+import org.codehaus.groovy.ast.expr.MethodCallExpression;
+import org.codehaus.groovy.ast.expr.PropertyExpression;
+import org.codehaus.groovy.ast.expr.SpreadExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.codehaus.groovy.ast.stmt.BlockStatement;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.ast.stmt.ReturnStatement;
+import org.codehaus.groovy.syntax.Token;
+import org.codehaus.groovy.syntax.Types;
+import org.objectweb.asm.Opcodes;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class InnerClassVisitorHelper extends ClassCodeVisitorSupport {
+    protected static void setPropertyGetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
+        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
+        gStringStrings.add(new ConstantExpression(""));
+        gStringStrings.add(new ConstantExpression(""));
+        List<Expression> gStringValues = new ArrayList<Expression>();
+        gStringValues.add(new VariableExpression(parameters[0]));
+        block.addStatement(
+                new ReturnStatement(
+                        new PropertyExpression(
+                                thiz,
+                                new GStringExpression("$name", gStringStrings, gStringValues)
+                        )
+                )
+        );
+    }
+
+    protected static void setPropertySetterDispatcher(BlockStatement block, Expression thiz, Parameter[] parameters) {
+        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
+        gStringStrings.add(new ConstantExpression(""));
+        gStringStrings.add(new ConstantExpression(""));
+        List<Expression> gStringValues = new ArrayList<Expression>();
+        gStringValues.add(new VariableExpression(parameters[0]));
+        block.addStatement(
+                new ExpressionStatement(
+                        new BinaryExpression(
+                                new PropertyExpression(
+                                        thiz,
+                                        new GStringExpression("$name", gStringStrings, gStringValues)
+                                ),
+                                Token.newSymbol(Types.ASSIGN, -1, -1),
+                                new VariableExpression(parameters[1])
+                        )
+                )
+        );
+    }
+
+    protected static void setMethodDispatcherCode(BlockStatement block, Expression thiz, Parameter[] parameters) {
+        List<ConstantExpression> gStringStrings = new ArrayList<ConstantExpression>();
+        gStringStrings.add(new ConstantExpression(""));
+        gStringStrings.add(new ConstantExpression(""));
+        List<Expression> gStringValues = new ArrayList<Expression>();
+        gStringValues.add(new VariableExpression(parameters[0]));
+        block.addStatement(
+                new ReturnStatement(
+                        new MethodCallExpression(
+                                thiz,
+                                new GStringExpression("$name", gStringStrings, gStringValues),
+                                new ArgumentListExpression(
+                                        new SpreadExpression(new VariableExpression(parameters[1]))
+                                )
+                        )
+                )
+        );
+    }
+
+    protected static boolean isStatic(InnerClassNode node) {
+        VariableScope scope = node.getVariableScope();
+        if (scope != null) return scope.getParent().isInStaticContext();
+        return (node.getModifiers() & Opcodes.ACC_STATIC) != 0;
+    }
+
+    protected static ClassNode getClassNode(ClassNode node, boolean isStatic) {
+        if (isStatic) node = ClassHelper.CLASS_Type;
+        return node;
+    }
+
+    protected static int getObjectDistance(ClassNode node) {
+        int count = 0;
+        while (node != null && node != ClassHelper.OBJECT_TYPE) {
+            count++;
+            node = node.getSuperClass();
+        }
+        return count;
+    }
+
+    protected static void addFieldInit(Parameter p, FieldNode fn, BlockStatement block) {
+        VariableExpression ve = new VariableExpression(p);
+        FieldExpression fe = new FieldExpression(fn);
+        block.addStatement(new ExpressionStatement(
+                new BinaryExpression(fe, Token.newSymbol(Types.ASSIGN, -1, -1), ve)
+        ));
+    }
+
+    protected static boolean shouldHandleImplicitThisForInnerClass(ClassNode cn) {
+        if (cn.isEnum() || cn.isInterface()) return false;
+        if ((cn.getModifiers() & Opcodes.ACC_STATIC) != 0) return false;
+
+        if (!(cn instanceof InnerClassNode)) return false;
+        InnerClassNode innerClass = (InnerClassNode) cn;
+        // scope != null means aic, we don't handle that here
+        if (innerClass.getVariableScope() != null) return false;
+        // static inner classes don't need this$0
+        return (innerClass.getModifiers() & Opcodes.ACC_STATIC) == 0;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/control/SourceExtensionHandler.java b/src/main/java/org/codehaus/groovy/control/SourceExtensionHandler.java
index 0ca38f5..09d788a 100644
--- a/src/main/java/org/codehaus/groovy/control/SourceExtensionHandler.java
+++ b/src/main/java/org/codehaus/groovy/control/SourceExtensionHandler.java
@@ -1,66 +1,66 @@
-/*
- *  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.control;
-
-import groovy.lang.GroovyRuntimeException;
-import org.codehaus.groovy.util.URLStreams;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.util.Enumeration;
-import java.util.LinkedHashSet;
-import java.util.Set;
-
-/**
- * Looks for source file extensions in META-INF/services/org.codehaus.groovy.source.Extensions
- */
-public class SourceExtensionHandler {
-
-    public static Set<String> getRegisteredExtensions(ClassLoader loader) {
-        Set<String> extensions = new LinkedHashSet<String>();
-        extensions.add("groovy");
-        try {
-            Enumeration<URL> globalServices = loader.getResources("META-INF/groovy/org.codehaus.groovy.source.Extensions");
-            if (!globalServices.hasMoreElements()) {
-                globalServices = loader.getResources("META-INF/services/org.codehaus.groovy.source.Extensions");
-            }
-            while (globalServices.hasMoreElements()) {
-                URL service = globalServices.nextElement();
-                try (BufferedReader svcIn = new BufferedReader(new InputStreamReader(URLStreams.openUncachedStream(service)))) {
-                    String extension = svcIn.readLine();
-                    while (extension != null) {
-                        extension = extension.trim();
-                        if (!extension.startsWith("#") && extension.length() > 0) {
-                            extensions.add(extension);
-                        }
-                        extension = svcIn.readLine();
-                    }
-                } catch (IOException ex) {
-                    throw new GroovyRuntimeException("IO Exception attempting to load registered source extension " +
-                            service.toExternalForm() + ". Exception: " + ex.toString());
-                }
-            }
-        } catch (IOException ex) {
-            throw new GroovyRuntimeException("IO Exception getting registered source extensions. Exception: " + ex.toString());
-        }
-        return extensions;
-    }
-}
+/*
+ *  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.control;
+
+import groovy.lang.GroovyRuntimeException;
+import org.codehaus.groovy.util.URLStreams;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * Looks for source file extensions in META-INF/services/org.codehaus.groovy.source.Extensions
+ */
+public class SourceExtensionHandler {
+
+    public static Set<String> getRegisteredExtensions(ClassLoader loader) {
+        Set<String> extensions = new LinkedHashSet<String>();
+        extensions.add("groovy");
+        try {
+            Enumeration<URL> globalServices = loader.getResources("META-INF/groovy/org.codehaus.groovy.source.Extensions");
+            if (!globalServices.hasMoreElements()) {
+                globalServices = loader.getResources("META-INF/services/org.codehaus.groovy.source.Extensions");
+            }
+            while (globalServices.hasMoreElements()) {
+                URL service = globalServices.nextElement();
+                try (BufferedReader svcIn = new BufferedReader(new InputStreamReader(URLStreams.openUncachedStream(service)))) {
+                    String extension = svcIn.readLine();
+                    while (extension != null) {
+                        extension = extension.trim();
+                        if (!extension.startsWith("#") && extension.length() > 0) {
+                            extensions.add(extension);
+                        }
+                        extension = svcIn.readLine();
+                    }
+                } catch (IOException ex) {
+                    throw new GroovyRuntimeException("IO Exception attempting to load registered source extension " +
+                            service.toExternalForm() + ". Exception: " + ex.toString());
+                }
+            }
+        } catch (IOException ex) {
+            throw new GroovyRuntimeException("IO Exception getting registered source extensions. Exception: " + ex.toString());
+        }
+        return extensions;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java b/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
index ebeb771..6069036 100644
--- a/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
+++ b/src/main/java/org/codehaus/groovy/reflection/ParameterTypes.java
@@ -1,385 +1,385 @@
-/*
- *  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.reflection;
-
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.runtime.MetaClassHelper;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-import org.codehaus.groovy.runtime.wrappers.Wrapper;
-
-import java.lang.reflect.Array;
-
-public class ParameterTypes {
-    private static final Class[] NO_PARAMETERS = new Class[0];
-
-    protected volatile Class[] nativeParamTypes;
-    protected volatile CachedClass[] parameterTypes;
-
-    protected boolean isVargsMethod;
-
-    public ParameterTypes() {
-    }
-
-    public ParameterTypes(Class pt[]) {
-        nativeParamTypes = pt;
-    }
-
-    public ParameterTypes(String pt[]) {
-        nativeParamTypes = new Class[pt.length];
-        for (int i = 0; i != pt.length; ++i) {
-            try {
-                nativeParamTypes[i] = Class.forName(pt[i]);
-            } catch (ClassNotFoundException e) {
-                NoClassDefFoundError err = new NoClassDefFoundError();
-                err.initCause(e);
-                throw err;
-            }
-        }
-    }
-
-    public ParameterTypes(CachedClass[] parameterTypes) {
-        setParametersTypes(parameterTypes);
-    }
-
-    protected final void setParametersTypes(CachedClass[] pt) {
-        this.parameterTypes = pt;
-        isVargsMethod = pt.length > 0 && pt[pt.length - 1].isArray;
-    }
-
-    public CachedClass[] getParameterTypes() {
-        if (parameterTypes == null) {
-            getParametersTypes0();
-        }
-
-        return parameterTypes;
-    }
-
-    private synchronized void getParametersTypes0() {
-        if (parameterTypes != null)
-            return;
-
-        Class[] npt = nativeParamTypes == null ? getPT() : nativeParamTypes;
-        if (npt.length == 0) {
-            nativeParamTypes = NO_PARAMETERS;
-            setParametersTypes(CachedClass.EMPTY_ARRAY);
-        } else {
-
-            CachedClass[] pt = new CachedClass[npt.length];
-            for (int i = 0; i != npt.length; ++i)
-                pt[i] = ReflectionCache.getCachedClass(npt[i]);
-
-            nativeParamTypes = npt;
-            setParametersTypes(pt);
-        }
-    }
-
-    public Class[] getNativeParameterTypes() {
-        if (nativeParamTypes == null) {
-            getNativeParameterTypes0();
-        }
-        return nativeParamTypes;
-    }
-
-    private synchronized void getNativeParameterTypes0() {
-        if (nativeParamTypes != null)
-            return;
-
-        Class[] npt;
-        if (parameterTypes != null) {
-            npt = new Class[parameterTypes.length];
-            for (int i = 0; i != parameterTypes.length; ++i) {
-                npt[i] = parameterTypes[i].getTheClass();
-            }
-        } else
-            npt = getPT();
-        nativeParamTypes = npt;
-    }
-
-    protected Class[] getPT() {
-        throw new UnsupportedOperationException(getClass().getName());
-    }
-
-    public boolean isVargsMethod() {
-        return isVargsMethod;
-    }
-
-    public boolean isVargsMethod(Object[] arguments) {
-        // Uncomment if at some point this method can be called before parameterTypes initialized
-        // getParameterTypes();
-        if (!isVargsMethod)
-            return false;
-
-        final int lenMinus1 = parameterTypes.length - 1;
-        // -1 because the varg part is optional
-        if (lenMinus1 == arguments.length) return true;
-        if (lenMinus1 > arguments.length) return false;
-        if (arguments.length > parameterTypes.length) return true;
-
-        // only case left is arguments.length == parameterTypes.length
-        Object last = arguments[arguments.length - 1];
-        if (last == null) return true;
-        Class clazz = last.getClass();
-        return !clazz.equals(parameterTypes[lenMinus1].getTheClass());
-
-    }
-
-    public final Object[] coerceArgumentsToClasses(Object[] argumentArray) {
-        // Uncomment if at some point this method can be called before parameterTypes initialized
-        // getParameterTypes();
-        argumentArray = correctArguments(argumentArray);
-
-        final CachedClass[] pt = parameterTypes;
-        final int len = argumentArray.length;
-        for (int i = 0; i < len; i++) {
-            final Object argument = argumentArray[i];
-            if (argument != null) {
-                argumentArray[i] = pt[i].coerceArgument(argument);
-            }
-        }
-        return argumentArray;
-    }
-
-    public Object[] correctArguments(Object[] argumentArray) {
-        // correct argumentArray's length
-        if (argumentArray == null) {
-            return MetaClassHelper.EMPTY_ARRAY;
-        }
-
-        final CachedClass[] pt = getParameterTypes();
-        if (pt.length == 1 && argumentArray.length == 0) {
-            if (isVargsMethod)
-                return new Object[]{Array.newInstance(pt[0].getTheClass().getComponentType(), 0)};
-            else
-                return MetaClassHelper.ARRAY_WITH_NULL;
-        }
-
-        if (isVargsMethod && isVargsMethod(argumentArray)) {
-            return fitToVargs(argumentArray, pt);
-        }
-
-        return argumentArray;
-    }
-
-    /**
-     * this method is called when the number of arguments to a method is greater than 1
-     * and if the method is a vargs method. This method will then transform the given
-     * arguments to make the method callable
-     *
-     * @param argumentArrayOrig the arguments used to call the method
-     * @param paramTypes        the types of the parameters the method takes
-     */
-    private static Object[] fitToVargs(Object[] argumentArrayOrig, CachedClass[] paramTypes) {
-        Class vargsClassOrig = paramTypes[paramTypes.length - 1].getTheClass().getComponentType();
-        Class vargsClass = ReflectionCache.autoboxType(vargsClassOrig);
-        Object[] argumentArray = argumentArrayOrig.clone();
-        MetaClassHelper.unwrap(argumentArray);
-
-        if (argumentArray.length == paramTypes.length - 1) {
-            // the vargs argument is missing, so fill it with an empty array
-            Object[] newArgs = new Object[paramTypes.length];
-            System.arraycopy(argumentArray, 0, newArgs, 0, argumentArray.length);
-            Object vargs = Array.newInstance(vargsClass, 0);
-            newArgs[newArgs.length - 1] = vargs;
-            return newArgs;
-        } else if (argumentArray.length == paramTypes.length) {
-            // the number of arguments is correct, but if the last argument
-            // is no array we have to wrap it in a array. If the last argument
-            // is null, then we don't have to do anything
-            Object lastArgument = argumentArray[argumentArray.length - 1];
-            if (lastArgument != null && !lastArgument.getClass().isArray()) {
-                // no array so wrap it
-                Object wrapped = makeCommonArray(argumentArray, paramTypes.length - 1, vargsClass);
-                Object[] newArgs = new Object[paramTypes.length];
-                System.arraycopy(argumentArray, 0, newArgs, 0, paramTypes.length - 1);
-                newArgs[newArgs.length - 1] = wrapped;
-                return newArgs;
-            } else {
-                // we may have to box the argument!
-                return argumentArray;
-            }
-        } else if (argumentArray.length > paramTypes.length) {
-            // the number of arguments is too big, wrap all exceeding elements
-            // in an array, but keep the old elements that are no vargs
-            Object[] newArgs = new Object[paramTypes.length];
-            // copy arguments that are not a varg
-            System.arraycopy(argumentArray, 0, newArgs, 0, paramTypes.length - 1);
-            // create a new array for the vargs and copy them
-            Object vargs = makeCommonArray(argumentArray, paramTypes.length - 1, vargsClass);
-            newArgs[newArgs.length - 1] = vargs;
-            return newArgs;
-        } else {
-            throw new GroovyBugError("trying to call a vargs method without enough arguments");
-        }
-    }
-
-    private static Object makeCommonArray(Object[] arguments, int offset, Class baseClass) {
-        Object[] result = (Object[]) Array.newInstance(baseClass, arguments.length - offset);
-        for (int i = offset; i < arguments.length; i++) {
-            Object v = arguments[i];
-            v = DefaultTypeTransformation.castToType(v, baseClass);
-            result[i - offset] = v;
-        }
-        return result;
-    }
-
-    public boolean isValidMethod(Class[] arguments) {
-        if (arguments == null) return true;
-
-        final int size = arguments.length;
-        CachedClass[] pt = getParameterTypes();
-        final int paramMinus1 = pt.length - 1;
-
-        if (isVargsMethod && size >= paramMinus1)
-            return isValidVarargsMethod(arguments, size, pt, paramMinus1);
-        else if (pt.length == size)
-            return isValidExactMethod(arguments, pt);
-        else if (pt.length == 1 && size == 0 && !pt[0].isPrimitive)
-            return true;
-        return false;
-    }
-
-    private static boolean isValidExactMethod(Class[] arguments, CachedClass[] pt) {
-        // lets check the parameter types match
-        int size = pt.length;
-        for (int i = 0; i < size; i++) {
-            if (!pt[i].isAssignableFrom(arguments[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean isValidExactMethod(Object[] args) {
-        // lets check the parameter types match
-        getParametersTypes0();
-        int size = args.length;
-        if (size != parameterTypes.length)
-            return false;
-
-        for (int i = 0; i < size; i++) {
-            if (args[i] != null && !parameterTypes[i].isAssignableFrom(args[i].getClass())) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    public boolean isValidExactMethod(Class[] args) {
-        // lets check the parameter types match
-        getParametersTypes0();
-        int size = args.length;
-        if (size != parameterTypes.length)
-            return false;
-
-        for (int i = 0; i < size; i++) {
-            if (args[i] != null && !parameterTypes[i].isAssignableFrom(args[i])) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    private static boolean testComponentAssignable(Class toTestAgainst, Class toTest) {
-        Class component = toTest.getComponentType();
-        if (component == null) return false;
-        return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
-    }
-
-    private static boolean isValidVarargsMethod(Class[] arguments, int size, CachedClass[] pt, int paramMinus1) {
-        // first check normal number of parameters
-        for (int i = 0; i < paramMinus1; i++) {
-            if (pt[i].isAssignableFrom(arguments[i])) continue;
-            return false;
-        }
-
-        // check direct match
-        CachedClass varg = pt[paramMinus1];
-        Class clazz = varg.getTheClass().getComponentType();
-        if (size == pt.length &&
-                (varg.isAssignableFrom(arguments[paramMinus1]) ||
-                        testComponentAssignable(clazz, arguments[paramMinus1]))) {
-            return true;
-        }
-
-        // check varged
-        for (int i = paramMinus1; i < size; i++) {
-            if (MetaClassHelper.isAssignableFrom(clazz, arguments[i])) continue;
-            return false;
-        }
-        return true;
-    }
-
-    public boolean isValidMethod(Object[] arguments) {
-        if (arguments == null) return true;
-
-        final int size = arguments.length;
-        CachedClass[] paramTypes = getParameterTypes();
-        final int paramMinus1 = paramTypes.length - 1;
-
-        if (size >= paramMinus1 && paramTypes.length > 0 &&
-                paramTypes[(paramMinus1)].isArray) {
-            // first check normal number of parameters
-            for (int i = 0; i < paramMinus1; i++) {
-                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) continue;
-                return false;
-            }
-
-
-            // check direct match
-            CachedClass varg = paramTypes[paramMinus1];
-            Class clazz = varg.getTheClass().getComponentType();
-            if (size == paramTypes.length &&
-                    (varg.isAssignableFrom(getArgClass(arguments[paramMinus1])) ||
-                            testComponentAssignable(clazz, getArgClass(arguments[paramMinus1])))) {
-                return true;
-            }
-
-
-            // check varged
-            for (int i = paramMinus1; i < size; i++) {
-                if (MetaClassHelper.isAssignableFrom(clazz, getArgClass(arguments[i]))) continue;
-                return false;
-            }
-            return true;
-        } else if (paramTypes.length == size) {
-            // lets check the parameter types match
-            for (int i = 0; i < size; i++) {
-                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) continue;
-                return false;
-            }
-            return true;
-        } else if (paramTypes.length == 1 && size == 0 && !paramTypes[0].isPrimitive) {
-            return true;
-        }
-        return false;
-    }
-
-    private static Class getArgClass(Object arg) {
-        Class cls;
-        if (arg == null) {
-            cls = null;
-        } else {
-            if (arg instanceof Wrapper) {
-                cls = ((Wrapper) arg).getType();
-            } else
-                cls = arg.getClass();
-        }
-        return cls;
-    }
-}
+/*
+ *  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.reflection;
+
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.runtime.MetaClassHelper;
+import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
+import org.codehaus.groovy.runtime.wrappers.Wrapper;
+
+import java.lang.reflect.Array;
+
+public class ParameterTypes {
+    private static final Class[] NO_PARAMETERS = new Class[0];
+
+    protected volatile Class[] nativeParamTypes;
+    protected volatile CachedClass[] parameterTypes;
+
+    protected boolean isVargsMethod;
+
+    public ParameterTypes() {
+    }
+
+    public ParameterTypes(Class pt[]) {
+        nativeParamTypes = pt;
+    }
+
+    public ParameterTypes(String pt[]) {
+        nativeParamTypes = new Class[pt.length];
+        for (int i = 0; i != pt.length; ++i) {
+            try {
+                nativeParamTypes[i] = Class.forName(pt[i]);
+            } catch (ClassNotFoundException e) {
+                NoClassDefFoundError err = new NoClassDefFoundError();
+                err.initCause(e);
+                throw err;
+            }
+        }
+    }
+
+    public ParameterTypes(CachedClass[] parameterTypes) {
+        setParametersTypes(parameterTypes);
+    }
+
+    protected final void setParametersTypes(CachedClass[] pt) {
+        this.parameterTypes = pt;
+        isVargsMethod = pt.length > 0 && pt[pt.length - 1].isArray;
+    }
+
+    public CachedClass[] getParameterTypes() {
+        if (parameterTypes == null) {
+            getParametersTypes0();
+        }
+
+        return parameterTypes;
+    }
+
+    private synchronized void getParametersTypes0() {
+        if (parameterTypes != null)
+            return;
+
+        Class[] npt = nativeParamTypes == null ? getPT() : nativeParamTypes;
+        if (npt.length == 0) {
+            nativeParamTypes = NO_PARAMETERS;
+            setParametersTypes(CachedClass.EMPTY_ARRAY);
+        } else {
+
+            CachedClass[] pt = new CachedClass[npt.length];
+            for (int i = 0; i != npt.length; ++i)
+                pt[i] = ReflectionCache.getCachedClass(npt[i]);
+
+            nativeParamTypes = npt;
+            setParametersTypes(pt);
+        }
+    }
+
+    public Class[] getNativeParameterTypes() {
+        if (nativeParamTypes == null) {
+            getNativeParameterTypes0();
+        }
+        return nativeParamTypes;
+    }
+
+    private synchronized void getNativeParameterTypes0() {
+        if (nativeParamTypes != null)
+            return;
+
+        Class[] npt;
+        if (parameterTypes != null) {
+            npt = new Class[parameterTypes.length];
+            for (int i = 0; i != parameterTypes.length; ++i) {
+                npt[i] = parameterTypes[i].getTheClass();
+            }
+        } else
+            npt = getPT();
+        nativeParamTypes = npt;
+    }
+
+    protected Class[] getPT() {
+        throw new UnsupportedOperationException(getClass().getName());
+    }
+
+    public boolean isVargsMethod() {
+        return isVargsMethod;
+    }
+
+    public boolean isVargsMethod(Object[] arguments) {
+        // Uncomment if at some point this method can be called before parameterTypes initialized
+        // getParameterTypes();
+        if (!isVargsMethod)
+            return false;
+
+        final int lenMinus1 = parameterTypes.length - 1;
+        // -1 because the varg part is optional
+        if (lenMinus1 == arguments.length) return true;
+        if (lenMinus1 > arguments.length) return false;
+        if (arguments.length > parameterTypes.length) return true;
+
+        // only case left is arguments.length == parameterTypes.length
+        Object last = arguments[arguments.length - 1];
+        if (last == null) return true;
+        Class clazz = last.getClass();
+        return !clazz.equals(parameterTypes[lenMinus1].getTheClass());
+
+    }
+
+    public final Object[] coerceArgumentsToClasses(Object[] argumentArray) {
+        // Uncomment if at some point this method can be called before parameterTypes initialized
+        // getParameterTypes();
+        argumentArray = correctArguments(argumentArray);
+
+        final CachedClass[] pt = parameterTypes;
+        final int len = argumentArray.length;
+        for (int i = 0; i < len; i++) {
+            final Object argument = argumentArray[i];
+            if (argument != null) {
+                argumentArray[i] = pt[i].coerceArgument(argument);
+            }
+        }
+        return argumentArray;
+    }
+
+    public Object[] correctArguments(Object[] argumentArray) {
+        // correct argumentArray's length
+        if (argumentArray == null) {
+            return MetaClassHelper.EMPTY_ARRAY;
+        }
+
+        final CachedClass[] pt = getParameterTypes();
+        if (pt.length == 1 && argumentArray.length == 0) {
+            if (isVargsMethod)
+                return new Object[]{Array.newInstance(pt[0].getTheClass().getComponentType(), 0)};
+            else
+                return MetaClassHelper.ARRAY_WITH_NULL;
+        }
+
+        if (isVargsMethod && isVargsMethod(argumentArray)) {
+            return fitToVargs(argumentArray, pt);
+        }
+
+        return argumentArray;
+    }
+
+    /**
+     * this method is called when the number of arguments to a method is greater than 1
+     * and if the method is a vargs method. This method will then transform the given
+     * arguments to make the method callable
+     *
+     * @param argumentArrayOrig the arguments used to call the method
+     * @param paramTypes        the types of the parameters the method takes
+     */
+    private static Object[] fitToVargs(Object[] argumentArrayOrig, CachedClass[] paramTypes) {
+        Class vargsClassOrig = paramTypes[paramTypes.length - 1].getTheClass().getComponentType();
+        Class vargsClass = ReflectionCache.autoboxType(vargsClassOrig);
+        Object[] argumentArray = argumentArrayOrig.clone();
+        MetaClassHelper.unwrap(argumentArray);
+
+        if (argumentArray.length == paramTypes.length - 1) {
+            // the vargs argument is missing, so fill it with an empty array
+            Object[] newArgs = new Object[paramTypes.length];
+            System.arraycopy(argumentArray, 0, newArgs, 0, argumentArray.length);
+            Object vargs = Array.newInstance(vargsClass, 0);
+            newArgs[newArgs.length - 1] = vargs;
+            return newArgs;
+        } else if (argumentArray.length == paramTypes.length) {
+            // the number of arguments is correct, but if the last argument
+            // is no array we have to wrap it in a array. If the last argument
+            // is null, then we don't have to do anything
+            Object lastArgument = argumentArray[argumentArray.length - 1];
+            if (lastArgument != null && !lastArgument.getClass().isArray()) {
+                // no array so wrap it
+                Object wrapped = makeCommonArray(argumentArray, paramTypes.length - 1, vargsClass);
+                Object[] newArgs = new Object[paramTypes.length];
+                System.arraycopy(argumentArray, 0, newArgs, 0, paramTypes.length - 1);
+                newArgs[newArgs.length - 1] = wrapped;
+                return newArgs;
+            } else {
+                // we may have to box the argument!
+                return argumentArray;
+            }
+        } else if (argumentArray.length > paramTypes.length) {
+            // the number of arguments is too big, wrap all exceeding elements
+            // in an array, but keep the old elements that are no vargs
+            Object[] newArgs = new Object[paramTypes.length];
+            // copy arguments that are not a varg
+            System.arraycopy(argumentArray, 0, newArgs, 0, paramTypes.length - 1);
+            // create a new array for the vargs and copy them
+            Object vargs = makeCommonArray(argumentArray, paramTypes.length - 1, vargsClass);
+            newArgs[newArgs.length - 1] = vargs;
+            return newArgs;
+        } else {
+            throw new GroovyBugError("trying to call a vargs method without enough arguments");
+        }
+    }
+
+    private static Object makeCommonArray(Object[] arguments, int offset, Class baseClass) {
+        Object[] result = (Object[]) Array.newInstance(baseClass, arguments.length - offset);
+        for (int i = offset; i < arguments.length; i++) {
+            Object v = arguments[i];
+            v = DefaultTypeTransformation.castToType(v, baseClass);
+            result[i - offset] = v;
+        }
+        return result;
+    }
+
+    public boolean isValidMethod(Class[] arguments) {
+        if (arguments == null) return true;
+
+        final int size = arguments.length;
+        CachedClass[] pt = getParameterTypes();
+        final int paramMinus1 = pt.length - 1;
+
+        if (isVargsMethod && size >= paramMinus1)
+            return isValidVarargsMethod(arguments, size, pt, paramMinus1);
+        else if (pt.length == size)
+            return isValidExactMethod(arguments, pt);
+        else if (pt.length == 1 && size == 0 && !pt[0].isPrimitive)
+            return true;
+        return false;
+    }
+
+    private static boolean isValidExactMethod(Class[] arguments, CachedClass[] pt) {
+        // lets check the parameter types match
+        int size = pt.length;
+        for (int i = 0; i < size; i++) {
+            if (!pt[i].isAssignableFrom(arguments[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean isValidExactMethod(Object[] args) {
+        // lets check the parameter types match
+        getParametersTypes0();
+        int size = args.length;
+        if (size != parameterTypes.length)
+            return false;
+
+        for (int i = 0; i < size; i++) {
+            if (args[i] != null && !parameterTypes[i].isAssignableFrom(args[i].getClass())) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public boolean isValidExactMethod(Class[] args) {
+        // lets check the parameter types match
+        getParametersTypes0();
+        int size = args.length;
+        if (size != parameterTypes.length)
+            return false;
+
+        for (int i = 0; i < size; i++) {
+            if (args[i] != null && !parameterTypes[i].isAssignableFrom(args[i])) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean testComponentAssignable(Class toTestAgainst, Class toTest) {
+        Class component = toTest.getComponentType();
+        if (component == null) return false;
+        return MetaClassHelper.isAssignableFrom(toTestAgainst, component);
+    }
+
+    private static boolean isValidVarargsMethod(Class[] arguments, int size, CachedClass[] pt, int paramMinus1) {
+        // first check normal number of parameters
+        for (int i = 0; i < paramMinus1; i++) {
+            if (pt[i].isAssignableFrom(arguments[i])) continue;
+            return false;
+        }
+
+        // check direct match
+        CachedClass varg = pt[paramMinus1];
+        Class clazz = varg.getTheClass().getComponentType();
+        if (size == pt.length &&
+                (varg.isAssignableFrom(arguments[paramMinus1]) ||
+                        testComponentAssignable(clazz, arguments[paramMinus1]))) {
+            return true;
+        }
+
+        // check varged
+        for (int i = paramMinus1; i < size; i++) {
+            if (MetaClassHelper.isAssignableFrom(clazz, arguments[i])) continue;
+            return false;
+        }
+        return true;
+    }
+
+    public boolean isValidMethod(Object[] arguments) {
+        if (arguments == null) return true;
+
+        final int size = arguments.length;
+        CachedClass[] paramTypes = getParameterTypes();
+        final int paramMinus1 = paramTypes.length - 1;
+
+        if (size >= paramMinus1 && paramTypes.length > 0 &&
+                paramTypes[(paramMinus1)].isArray) {
+            // first check normal number of parameters
+            for (int i = 0; i < paramMinus1; i++) {
+                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) continue;
+                return false;
+            }
+
+
+            // check direct match
+            CachedClass varg = paramTypes[paramMinus1];
+            Class clazz = varg.getTheClass().getComponentType();
+            if (size == paramTypes.length &&
+                    (varg.isAssignableFrom(getArgClass(arguments[paramMinus1])) ||
+                            testComponentAssignable(clazz, getArgClass(arguments[paramMinus1])))) {
+                return true;
+            }
+
+
+            // check varged
+            for (int i = paramMinus1; i < size; i++) {
+                if (MetaClassHelper.isAssignableFrom(clazz, getArgClass(arguments[i]))) continue;
+                return false;
+            }
+            return true;
+        } else if (paramTypes.length == size) {
+            // lets check the parameter types match
+            for (int i = 0; i < size; i++) {
+                if (paramTypes[i].isAssignableFrom(getArgClass(arguments[i]))) continue;
+                return false;
+            }
+            return true;
+        } else if (paramTypes.length == 1 && size == 0 && !paramTypes[0].isPrimitive) {
+            return true;
+        }
+        return false;
+    }
+
+    private static Class getArgClass(Object arg) {
+        Class cls;
+        if (arg == null) {
+            cls = null;
+        } else {
+            if (arg instanceof Wrapper) {
+                cls = ((Wrapper) arg).getType();
+            } else
+                cls = arg.getClass();
+        }
+        return cls;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
index bed1a48..59c86d2 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ConversionHandler.java
@@ -1,226 +1,226 @@
-/*
- *  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.runtime;
-
-import groovy.lang.GroovyObject;
-import groovy.lang.GroovyRuntimeException;
-import groovy.lang.GroovySystem;
-import groovy.lang.MetaClass;
-import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;
-import org.codehaus.groovy.vmplugin.VMPlugin;
-import org.codehaus.groovy.vmplugin.VMPluginFactory;
-
-import java.io.Serializable;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.lang.reflect.Proxy;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-/**
- * This class is a general adapter to map a call to a Java interface
- * to a given delegate.
- */
-public abstract class ConversionHandler implements InvocationHandler, Serializable {
-    private final Object delegate;
-    private static final long serialVersionUID = 1162833717190835227L;
-    private final ConcurrentHashMap<Method, Object> handleCache;
-    {
-        if (VMPluginFactory.getPlugin().getVersion() >= 7) {
-            handleCache = new ConcurrentHashMap<Method, Object>(16, 0.9f, 2);
-        } else {
-            handleCache = null;
-        }
-    }
-
-    private MetaClass metaClass;
-
-    /**
-     * Creates a ConversionHandler with an delegate.
-     *
-     * @param delegate the delegate
-     * @throws IllegalArgumentException if the given delegate is null
-     */
-    public ConversionHandler(Object delegate) {
-        if (delegate == null) {
-            throw new IllegalArgumentException("delegate must not be null");
-        }
-        this.delegate = delegate;
-    }
-
-    /**
-     * Returns the delegate.
-     *
-     * @return the delegate
-     */
-    public Object getDelegate() {
-        return delegate;
-    }
-
-    /**
-     * This method is a default implementation for the invoke method given in
-     * InvocationHandler. Any call to a method with a declaring class that is
-     * not Object, excluding toString() and default methods is redirected to invokeCustom.
-     * <p>
-     * Methods like equals and hashcode are called on the class itself instead
-     * of the delegate because they are considered fundamental methods that should
-     * not be overwritten. The toString() method gets special treatment as it is
-     * deemed to be a method that you might wish to override when called from Groovy.
-     * Interface default methods from Java 8 on the other hand are considered being
-     * default implementations you don't normally want to change. So they are called
-     * directly too
-     * </p><p>
-     * In many scenarios, it is better to overwrite the invokeCustom method where
-     * the core Object related methods are filtered out.
-     *</p>
-     * @param proxy  the proxy
-     * @param method the method
-     * @param args   the arguments
-     * @return the result of the invocation by method or delegate
-     * @throws Throwable if caused by the delegate or the method
-     * @see #invokeCustom(Object, Method, Object[])
-     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
-     */
-    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-        if (handleCache != null && isDefaultMethod(method) && !defaultOverridden(method)) {
-            VMPlugin plugin = VMPluginFactory.getPlugin();
-            Object handle = handleCache.get(method);
-            if (handle == null) {
-                handle = plugin.getInvokeSpecialHandle(method, proxy);
-                handleCache.put(method, handle);
-            }
-            return plugin.invokeHandle(handle, args);
-        }
-
-        if (!checkMethod(method)) {
-            try {
-                if (method.getDeclaringClass() == GroovyObject.class) {
-                    if ("getMetaClass".equals(method.getName())) {
-                        return getMetaClass(proxy);
-                    } else if ("setMetaClass".equals(method.getName())) {
-                        return setMetaClass((MetaClass) args[0]);
-                    }
-                }
-                return invokeCustom(proxy, method, args);
-            } catch (GroovyRuntimeException gre) {
-                throw ScriptBytecodeAdapter.unwrap(gre);
-            }
-        }
-
-        try {
-            return method.invoke(this, args);
-        } catch (InvocationTargetException ite) {
-            throw ite.getTargetException();
-        }
-    }
-
-    private boolean defaultOverridden(Method method) {
-        return delegate instanceof Map && ((Map) delegate).containsKey(method.getName());
-    }
-
-    protected boolean isDefaultMethod(Method method) {
-        return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
-                Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
-    }
-
-    protected boolean checkMethod(Method method) {
-        return isCoreObjectMethod(method);
-    }
-
-    /**
-     * This method is called for all Methods not defined on Object.
-     * The delegate should be called here.
-     *
-     * @param proxy  the proxy
-     * @param method the method
-     * @param args   the arguments
-     * @return the result of the invocation of the delegate
-     * @throws Throwable any exception causes by the delegate
-     * @see #invoke(Object, Method, Object[])
-     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
-     */
-    public abstract Object invokeCustom(Object proxy, Method method, Object[] args) throws Throwable;
-
-    /**
-     * Indicates whether some other object is "equal to" this one.
-     * The delegate is used if the class of the parameter and the
-     * current class are equal. In other cases the method will return
-     * false. The exact class is here used, if inheritance is needed,
-     * this method must be overwritten.
-     *
-     * @see java.lang.Object#equals(java.lang.Object)
-     */
-    public boolean equals(Object obj) {
-        if (obj instanceof Proxy) {
-            obj = Proxy.getInvocationHandler(obj);
-        }
-
-        if (obj instanceof ConversionHandler) {
-            return (((ConversionHandler) obj).getDelegate()).equals(delegate);
-        } else {
-            return false;
-        }
-    }
-
-    /**
-     * Returns a hash code value for the delegate.
-     *
-     * @see java.lang.Object#hashCode()
-     */
-    public int hashCode() {
-        return delegate.hashCode();
-    }
-
-    /**
-     * Returns a String version of the delegate.
-     *
-     * @see java.lang.Object#toString()
-     */
-    public String toString() {
-        return delegate.toString();
-    }
-
-    /**
-     * Checks whether a method is a core method from java.lang.Object.
-     * Such methods often receive special treatment because they are
-     * deemed fundamental enough to not be tampered with.
-     *
-     * @param method the method to check
-     * @return true if the method is deemed to be a core method
-     */
-    public static boolean isCoreObjectMethod(Method method) {
-        return Object.class.equals(method.getDeclaringClass());
-    }
-
-    private MetaClass setMetaClass(MetaClass mc) {
-        metaClass = mc;
-        return mc;
-    }
-
-    private MetaClass getMetaClass(Object proxy) {
-        MetaClass mc = metaClass;
-        if (mc == null) {
-            mc = ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(proxy);
-            metaClass = mc;
-        }
-        return mc;
-    }
-}
+/*
+ *  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.runtime;
+
+import groovy.lang.GroovyObject;
+import groovy.lang.GroovyRuntimeException;
+import groovy.lang.GroovySystem;
+import groovy.lang.MetaClass;
+import org.codehaus.groovy.runtime.metaclass.MetaClassRegistryImpl;
+import org.codehaus.groovy.vmplugin.VMPlugin;
+import org.codehaus.groovy.vmplugin.VMPluginFactory;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class is a general adapter to map a call to a Java interface
+ * to a given delegate.
+ */
+public abstract class ConversionHandler implements InvocationHandler, Serializable {
+    private final Object delegate;
+    private static final long serialVersionUID = 1162833717190835227L;
+    private final ConcurrentHashMap<Method, Object> handleCache;
+    {
+        if (VMPluginFactory.getPlugin().getVersion() >= 7) {
+            handleCache = new ConcurrentHashMap<Method, Object>(16, 0.9f, 2);
+        } else {
+            handleCache = null;
+        }
+    }
+
+    private MetaClass metaClass;
+
+    /**
+     * Creates a ConversionHandler with an delegate.
+     *
+     * @param delegate the delegate
+     * @throws IllegalArgumentException if the given delegate is null
+     */
+    public ConversionHandler(Object delegate) {
+        if (delegate == null) {
+            throw new IllegalArgumentException("delegate must not be null");
+        }
+        this.delegate = delegate;
+    }
+
+    /**
+     * Returns the delegate.
+     *
+     * @return the delegate
+     */
+    public Object getDelegate() {
+        return delegate;
+    }
+
+    /**
+     * This method is a default implementation for the invoke method given in
+     * InvocationHandler. Any call to a method with a declaring class that is
+     * not Object, excluding toString() and default methods is redirected to invokeCustom.
+     * <p>
+     * Methods like equals and hashcode are called on the class itself instead
+     * of the delegate because they are considered fundamental methods that should
+     * not be overwritten. The toString() method gets special treatment as it is
+     * deemed to be a method that you might wish to override when called from Groovy.
+     * Interface default methods from Java 8 on the other hand are considered being
+     * default implementations you don't normally want to change. So they are called
+     * directly too
+     * </p><p>
+     * In many scenarios, it is better to overwrite the invokeCustom method where
+     * the core Object related methods are filtered out.
+     *</p>
+     * @param proxy  the proxy
+     * @param method the method
+     * @param args   the arguments
+     * @return the result of the invocation by method or delegate
+     * @throws Throwable if caused by the delegate or the method
+     * @see #invokeCustom(Object, Method, Object[])
+     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+        if (handleCache != null && isDefaultMethod(method) && !defaultOverridden(method)) {
+            VMPlugin plugin = VMPluginFactory.getPlugin();
+            Object handle = handleCache.get(method);
+            if (handle == null) {
+                handle = plugin.getInvokeSpecialHandle(method, proxy);
+                handleCache.put(method, handle);
+            }
+            return plugin.invokeHandle(handle, args);
+        }
+
+        if (!checkMethod(method)) {
+            try {
+                if (method.getDeclaringClass() == GroovyObject.class) {
+                    if ("getMetaClass".equals(method.getName())) {
+                        return getMetaClass(proxy);
+                    } else if ("setMetaClass".equals(method.getName())) {
+                        return setMetaClass((MetaClass) args[0]);
+                    }
+                }
+                return invokeCustom(proxy, method, args);
+            } catch (GroovyRuntimeException gre) {
+                throw ScriptBytecodeAdapter.unwrap(gre);
+            }
+        }
+
+        try {
+            return method.invoke(this, args);
+        } catch (InvocationTargetException ite) {
+            throw ite.getTargetException();
+        }
+    }
+
+    private boolean defaultOverridden(Method method) {
+        return delegate instanceof Map && ((Map) delegate).containsKey(method.getName());
+    }
+
+    protected boolean isDefaultMethod(Method method) {
+        return ((method.getModifiers() & (Modifier.ABSTRACT | Modifier.PUBLIC | Modifier.STATIC)) ==
+                Modifier.PUBLIC) && method.getDeclaringClass().isInterface();
+    }
+
+    protected boolean checkMethod(Method method) {
+        return isCoreObjectMethod(method);
+    }
+
+    /**
+     * This method is called for all Methods not defined on Object.
+     * The delegate should be called here.
+     *
+     * @param proxy  the proxy
+     * @param method the method
+     * @param args   the arguments
+     * @return the result of the invocation of the delegate
+     * @throws Throwable any exception causes by the delegate
+     * @see #invoke(Object, Method, Object[])
+     * @see InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
+     */
+    public abstract Object invokeCustom(Object proxy, Method method, Object[] args) throws Throwable;
+
+    /**
+     * Indicates whether some other object is "equal to" this one.
+     * The delegate is used if the class of the parameter and the
+     * current class are equal. In other cases the method will return
+     * false. The exact class is here used, if inheritance is needed,
+     * this method must be overwritten.
+     *
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public boolean equals(Object obj) {
+        if (obj instanceof Proxy) {
+            obj = Proxy.getInvocationHandler(obj);
+        }
+
+        if (obj instanceof ConversionHandler) {
+            return (((ConversionHandler) obj).getDelegate()).equals(delegate);
+        } else {
+            return false;
+        }
+    }
+
+    /**
+     * Returns a hash code value for the delegate.
+     *
+     * @see java.lang.Object#hashCode()
+     */
+    public int hashCode() {
+        return delegate.hashCode();
+    }
+
+    /**
+     * Returns a String version of the delegate.
+     *
+     * @see java.lang.Object#toString()
+     */
+    public String toString() {
+        return delegate.toString();
+    }
+
+    /**
+     * Checks whether a method is a core method from java.lang.Object.
+     * Such methods often receive special treatment because they are
+     * deemed fundamental enough to not be tampered with.
+     *
+     * @param method the method to check
+     * @return true if the method is deemed to be a core method
+     */
+    public static boolean isCoreObjectMethod(Method method) {
+        return Object.class.equals(method.getDeclaringClass());
+    }
+
+    private MetaClass setMetaClass(MetaClass mc) {
+        metaClass = mc;
+        return mc;
+    }
+
+    private MetaClass getMetaClass(Object proxy) {
+        MetaClass mc = metaClass;
+        if (mc == null) {
+            mc = ((MetaClassRegistryImpl) GroovySystem.getMetaClassRegistry()).getMetaClass(proxy);
+            metaClass = mc;
+        }
+        return mc;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java b/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
index 84a627f..f21b143 100644
--- a/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
+++ b/src/main/java/org/codehaus/groovy/runtime/ConvertedClosure.java
@@ -1,54 +1,54 @@
-/*
- *  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.runtime;
-
-import groovy.lang.Closure;
-
-import java.io.Serializable;
-import java.lang.reflect.Method;
-
-/**
- * This class is a general adapter to adapt a closure to any Java interface.
- */
-public class ConvertedClosure extends ConversionHandler implements Serializable {
-    private final String methodName;
-    private static final long serialVersionUID = 1162833713450835227L;
-
-    /**
-     * to create a ConvertedClosure object.
-     * @param closure the closure object.
-     */
-    public ConvertedClosure(Closure closure, String method) {
-        super(closure);
-        this.methodName = method;
-    }
-    
-    public ConvertedClosure(Closure closure) {
-        this(closure,null);
-    }
-
-    @Override
-    public Object invokeCustom(Object proxy, Method method, Object[] args)
-    throws Throwable {
-        if (methodName!=null && !methodName.equals(method.getName())) return null;
-        return ((Closure) getDelegate()).call(args);
-    }
-
-}
-
+/*
+ *  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.runtime;
+
+import groovy.lang.Closure;
+
+import java.io.Serializable;
+import java.lang.reflect.Method;
+
+/**
+ * This class is a general adapter to adapt a closure to any Java interface.
+ */
+public class ConvertedClosure extends ConversionHandler implements Serializable {
+    private final String methodName;
+    private static final long serialVersionUID = 1162833713450835227L;
+
+    /**
+     * to create a ConvertedClosure object.
+     * @param closure the closure object.
+     */
+    public ConvertedClosure(Closure closure, String method) {
+        super(closure);
+        this.methodName = method;
+    }
+    
+    public ConvertedClosure(Closure closure) {
+        this(closure,null);
+    }
+
+    @Override
+    public Object invokeCustom(Object proxy, Method method, Object[] args)
+    throws Throwable {
+        if (methodName!=null && !methodName.equals(method.getName())) return null;
+        return ((Closure) getDelegate()).call(args);
+    }
+
+}
+
diff --git a/src/main/java/org/codehaus/groovy/runtime/EncodingGroovyMethodsSupport.java b/src/main/java/org/codehaus/groovy/runtime/EncodingGroovyMethodsSupport.java
index 24929a8..9a97fc3 100644
--- a/src/main/java/org/codehaus/groovy/runtime/EncodingGroovyMethodsSupport.java
+++ b/src/main/java/org/codehaus/groovy/runtime/EncodingGroovyMethodsSupport.java
@@ -1,90 +1,90 @@
-/*
- *  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.runtime;
-
-/**
- * Keep this constant in a separate file as it is troublesome for Antlr to parse for doc purposes.
- */
-public class EncodingGroovyMethodsSupport {
-    static final byte[] TRANSLATE_TABLE = (
-            "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //           \t    \n                \r
-                    + "\u0042\u0041\u0041\u0042\u0042\u0041\u0042\u0042"
-                    //
-                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //
-                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //     sp     !     "     #     $     %     &     '
-                    + "\u0041\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //      (     )     *     +     ,     -     .     /
-                    + "\u0042\u0042\u0042\u003E\u0042\u0042\u0042\u003F"
-                    //      0     1     2     3     4     5     6     7
-                    + "\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B"
-                    //      8     9     :     ;     <     =     >     ?
-                    + "\u003C\u003D\u0042\u0042\u0042\u0040\u0042\u0042"
-                    //      @     A     B     C     D     E     F     G
-                    + "\u0042\u0000\u0001\u0002\u0003\u0004\u0005\u0006"
-                    //      H     I J K     L     M N     O
-                    + "\u0007\u0008\t\n\u000B\u000C\r\u000E"
-                    //      P     Q     R     S     T     U     V     W
-                    + "\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016"
-                    //      X     Y     Z     [     \     ]     ^     _
-                    + "\u0017\u0018\u0019\u0042\u0042\u0042\u0042\u0042"
-                    //      '     a     b     c     d     e     f     g
-                    + "\u0042\u001A\u001B\u001C\u001D\u001E\u001F\u0020"
-                    //      h i     j     k     l     m     n     o
-                    + "\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028"
-                    //      p     q     r     s     t     u     v     w
-                    + "\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030"
-                    //      x     y     z
-                    + "\u0031\u0032\u0033").getBytes();
-
-    static final byte[] TRANSLATE_TABLE_URLSAFE = (
-            "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //           \t    \n                \r
-                    + "\u0042\u0041\u0041\u0042\u0042\u0041\u0042\u0042"
-                    //
-                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //
-                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //     sp     !     "     #     $     %     &     '
-                    + "\u0041\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
-                    //      (     )     *     +     ,     -     .     /
-                    + "\u0042\u0042\u0042\u0042\u0042\u003E\u0042\u0042"
-                    //      0     1     2     3     4     5     6     7
-                    + "\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B"
-                    //      8     9     :     ;     <     =     >     ?
-                    + "\u003C\u003D\u0042\u0042\u0042\u0040\u0042\u0042"
-                    //      @     A     B     C     D     E     F     G
-                    + "\u0042\u0000\u0001\u0002\u0003\u0004\u0005\u0006"
-                    //      H     I J K     L     M N     O
-                    + "\u0007\u0008\t\n\u000B\u000C\r\u000E"
-                    //      P     Q     R     S     T     U     V     W
-                    + "\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016"
-                    //      X     Y     Z     [     \     ]     ^     _
-                    + "\u0017\u0018\u0019\u0042\u0042\u0042\u0042\u003F"
-                    //      '     a     b     c     d     e     f     g
-                    + "\u0042\u001A\u001B\u001C\u001D\u001E\u001F\u0020"
-                    //      h i     j     k     l     m     n     o
-                    + "\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028"
-                    //      p     q     r     s     t     u     v     w
-                    + "\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030"
-                    //      x     y     z
-                    + "\u0031\u0032\u0033").getBytes();
-}
+/*
+ *  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.runtime;
+
+/**
+ * Keep this constant in a separate file as it is troublesome for Antlr to parse for doc purposes.
+ */
+public class EncodingGroovyMethodsSupport {
+    static final byte[] TRANSLATE_TABLE = (
+            "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //           \t    \n                \r
+                    + "\u0042\u0041\u0041\u0042\u0042\u0041\u0042\u0042"
+                    //
+                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //
+                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //     sp     !     "     #     $     %     &     '
+                    + "\u0041\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //      (     )     *     +     ,     -     .     /
+                    + "\u0042\u0042\u0042\u003E\u0042\u0042\u0042\u003F"
+                    //      0     1     2     3     4     5     6     7
+                    + "\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B"
+                    //      8     9     :     ;     <     =     >     ?
+                    + "\u003C\u003D\u0042\u0042\u0042\u0040\u0042\u0042"
+                    //      @     A     B     C     D     E     F     G
+                    + "\u0042\u0000\u0001\u0002\u0003\u0004\u0005\u0006"
+                    //      H     I J K     L     M N     O
+                    + "\u0007\u0008\t\n\u000B\u000C\r\u000E"
+                    //      P     Q     R     S     T     U     V     W
+                    + "\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016"
+                    //      X     Y     Z     [     \     ]     ^     _
+                    + "\u0017\u0018\u0019\u0042\u0042\u0042\u0042\u0042"
+                    //      '     a     b     c     d     e     f     g
+                    + "\u0042\u001A\u001B\u001C\u001D\u001E\u001F\u0020"
+                    //      h i     j     k     l     m     n     o
+                    + "\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028"
+                    //      p     q     r     s     t     u     v     w
+                    + "\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030"
+                    //      x     y     z
+                    + "\u0031\u0032\u0033").getBytes();
+
+    static final byte[] TRANSLATE_TABLE_URLSAFE = (
+            "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //           \t    \n                \r
+                    + "\u0042\u0041\u0041\u0042\u0042\u0041\u0042\u0042"
+                    //
+                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //
+                    + "\u0042\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //     sp     !     "     #     $     %     &     '
+                    + "\u0041\u0042\u0042\u0042\u0042\u0042\u0042\u0042"
+                    //      (     )     *     +     ,     -     .     /
+                    + "\u0042\u0042\u0042\u0042\u0042\u003E\u0042\u0042"
+                    //      0     1     2     3     4     5     6     7
+                    + "\u0034\u0035\u0036\u0037\u0038\u0039\u003A\u003B"
+                    //      8     9     :     ;     <     =     >     ?
+                    + "\u003C\u003D\u0042\u0042\u0042\u0040\u0042\u0042"
+                    //      @     A     B     C     D     E     F     G
+                    + "\u0042\u0000\u0001\u0002\u0003\u0004\u0005\u0006"
+                    //      H     I J K     L     M N     O
+                    + "\u0007\u0008\t\n\u000B\u000C\r\u000E"
+                    //      P     Q     R     S     T     U     V     W
+                    + "\u000F\u0010\u0011\u0012\u0013\u0014\u0015\u0016"
+                    //      X     Y     Z     [     \     ]     ^     _
+                    + "\u0017\u0018\u0019\u0042\u0042\u0042\u0042\u003F"
+                    //      '     a     b     c     d     e     f     g
+                    + "\u0042\u001A\u001B\u001C\u001D\u001E\u001F\u0020"
+                    //      h i     j     k     l     m     n     o
+                    + "\u0021\"\u0023\u0024\u0025\u0026\u0027\u0028"
+                    //      p     q     r     s     t     u     v     w
+                    + "\u0029\u002A\u002B\u002C\u002D\u002E\u002F\u0030"
+                    //      x     y     z
+                    + "\u0031\u0032\u0033").getBytes();
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java b/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java
index 7e5beec..b1c66fe 100644
--- a/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java
+++ b/src/main/java/org/codehaus/groovy/runtime/GStringImpl.java
@@ -1,64 +1,64 @@
-/*
- * 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.runtime;
-
-import groovy.lang.GString;
-
-/**
- * Default implementation of a GString used by the compiler. A GString
- * consist of a list of values and strings which can be combined to
- * create a new String.
- *
- * @see groovy.lang.GString
- */
-public class GStringImpl extends GString {
-    private static final long serialVersionUID = 3581289038662723858L;
-    private String[] strings;
-
-    /**
-     * Create a new GString with values and strings.
-     * <p>
-     * Each value is prefixed by a string, after the last value
-     * an additional String might be used. This means
-     * <code>strings.length == values.length  ||  strings.length == values.length + 1</code>.
-     * <p>
-     * <b>NOTE:</b> The lengths are <b>not</b> checked. Using different lengths might result
-     * in unpredictable behaviour.
-     *
-     * @param values  the value parts
-     * @param strings the string parts
-     */
-    public GStringImpl(Object[] values, String[] strings) {
-        super(values);
-        this.strings = strings;
-    }
-
-    /**
-     * Get the strings of this GString.
-     * <p>
-     * This methods returns the same array as used in the constructor. Changing
-     * the values will result in changes of the GString. It is not recommended
-     * to do so.
-     */
-    public String[] getStrings() {
-        return strings;
-    }
-
-}
+/*
+ * 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.runtime;
+
+import groovy.lang.GString;
+
+/**
+ * Default implementation of a GString used by the compiler. A GString
+ * consist of a list of values and strings which can be combined to
+ * create a new String.
+ *
+ * @see groovy.lang.GString
+ */
+public class GStringImpl extends GString {
+    private static final long serialVersionUID = 3581289038662723858L;
+    private String[] strings;
+
+    /**
+     * Create a new GString with values and strings.
+     * <p>
+     * Each value is prefixed by a string, after the last value
+     * an additional String might be used. This means
+     * <code>strings.length == values.length  ||  strings.length == values.length + 1</code>.
+     * <p>
+     * <b>NOTE:</b> The lengths are <b>not</b> checked. Using different lengths might result
+     * in unpredictable behaviour.
+     *
+     * @param values  the value parts
+     * @param strings the string parts
+     */
+    public GStringImpl(Object[] values, String[] strings) {
+        super(values);
+        this.strings = strings;
+    }
+
+    /**
+     * Get the strings of this GString.
+     * <p>
+     * This methods returns the same array as used in the constructor. Changing
+     * the values will result in changes of the GString. It is not recommended
+     * to do so.
+     */
+    public String[] getStrings() {
+        return strings;
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/NumberAwareComparator.java b/src/main/java/org/codehaus/groovy/runtime/NumberAwareComparator.java
index c44a48e..6a11b03 100644
--- a/src/main/java/org/codehaus/groovy/runtime/NumberAwareComparator.java
+++ b/src/main/java/org/codehaus/groovy/runtime/NumberAwareComparator.java
@@ -1,56 +1,56 @@
-/*
- *  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.runtime;
-
-import groovy.lang.GroovyRuntimeException;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-import java.io.Serializable;
-import java.util.Comparator;
-
-/**
- * Compares two objects using Groovy's friendly comparison algorithm, i.e.
- * handles nulls gracefully (nul being less than everything else) and
- * performs numeric type coercion if required.
- */
-public class NumberAwareComparator<T> implements Comparator<T>, Serializable {
-    private static final long serialVersionUID = 9017657289076651660L;
-
-    public int compare(T o1, T o2) {
-        try {
-            return DefaultTypeTransformation.compareTo(o1, o2);
-        } catch (ClassCastException | IllegalArgumentException | GroovyRuntimeException cce) {
-            /* ignore */
-        }
-        // since the object does not have a valid compareTo method
-        // we compare using the hashcodes. null cases are handled by
-        // DefaultTypeTransformation.compareTo
-        // This is not exactly a mathematical valid approach, since we compare object
-        // that cannot be compared. To avoid strange side effects we do a pseudo order
-        // using hashcodes, but without equality. Since then an x and y with the same
-        // hashcodes will behave different depending on if we compare x with y or
-        // x with y, the result might be unstable as well. Setting x and y to equal
-        // may mean the removal of x or y in a sorting operation, which we don't want.
-        int x1 = o1.hashCode();
-        int x2 = o2.hashCode();
-        if (x1 == x2 && o1.equals(o2)) return 0;
-        if (x1 > x2) return 1;
-        return -1;
-    }
-}
+/*
+ *  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.runtime;
+
+import groovy.lang.GroovyRuntimeException;
+import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+/**
+ * Compares two objects using Groovy's friendly comparison algorithm, i.e.
+ * handles nulls gracefully (nul being less than everything else) and
+ * performs numeric type coercion if required.
+ */
+public class NumberAwareComparator<T> implements Comparator<T>, Serializable {
+    private static final long serialVersionUID = 9017657289076651660L;
+
+    public int compare(T o1, T o2) {
+        try {
+            return DefaultTypeTransformation.compareTo(o1, o2);
+        } catch (ClassCastException | IllegalArgumentException | GroovyRuntimeException cce) {
+            /* ignore */
+        }
+        // since the object does not have a valid compareTo method
+        // we compare using the hashcodes. null cases are handled by
+        // DefaultTypeTransformation.compareTo
+        // This is not exactly a mathematical valid approach, since we compare object
+        // that cannot be compared. To avoid strange side effects we do a pseudo order
+        // using hashcodes, but without equality. Since then an x and y with the same
+        // hashcodes will behave different depending on if we compare x with y or
+        // x with y, the result might be unstable as well. Setting x and y to equal
+        // may mean the removal of x or y in a sorting operation, which we don't want.
+        int x1 = o1.hashCode();
+        int x2 = o2.hashCode();
+        if (x1 == x2 && o1.equals(o2)) return 0;
+        if (x1 > x2) return 1;
+        return -1;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/CharacterArrayPutAtMetaMethod.java b/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/CharacterArrayPutAtMetaMethod.java
index 053b7d4..039e21c 100644
--- a/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/CharacterArrayPutAtMetaMethod.java
+++ b/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/CharacterArrayPutAtMetaMethod.java
@@ -1,86 +1,86 @@
-/*
- *  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.runtime.dgmimpl.arrays;
-
-import groovy.lang.MetaClassImpl;
-import groovy.lang.MetaMethod;
-import org.codehaus.groovy.reflection.CachedClass;
-import org.codehaus.groovy.reflection.ReflectionCache;
-import org.codehaus.groovy.runtime.callsite.CallSite;
-import org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-public class CharacterArrayPutAtMetaMethod extends ArrayPutAtMetaMethod {
-    private static final CachedClass OBJECT_CLASS = ReflectionCache.OBJECT_CLASS;
-    private static final CachedClass ARR_CLASS = ReflectionCache.getCachedClass(char[].class);
-    private static final CachedClass[] PARAM_CLASS_ARR = new CachedClass[]{INTEGER_CLASS, OBJECT_CLASS};
-
-    public CharacterArrayPutAtMetaMethod() {
-        parameterTypes = PARAM_CLASS_ARR;
-    }
-
-    public final CachedClass getDeclaringClass() {
-        return ARR_CLASS;
-    }
-
-    public Object invoke(Object object, Object[] args) {
-        final char[] objects = (char[]) object;
-        final int index = normaliseIndex((Integer) args[0], objects.length);
-        objects[index] = DefaultTypeTransformation.getCharFromSizeOneString(args[1]);
-        return null;
-    }
-
-    public CallSite createPojoCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) {
-        if (!(args[0] instanceof Integer) || !(args[1] instanceof Character))
-            return PojoMetaMethodSite.createNonAwareCallSite(site, metaClass, metaMethod, params, args);
-        else
-            return new MyPojoMetaMethodSite(site, metaClass, metaMethod, params);
-    }
-
-    private static class MyPojoMetaMethodSite extends PojoMetaMethodSite {
-        public MyPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params) {
-            super(site, metaClass, metaMethod, params);
-        }
-
-        public Object call(Object receiver, Object[] args) throws Throwable {
-            if ((receiver instanceof char[] && args[0] instanceof Integer && args[1] instanceof Character)
-                    && checkPojoMetaClass()) {
-                final char[] objects = (char[]) receiver;
-                objects[normaliseIndex((Integer) args[0], objects.length)] = (Character) args[1];
-                return null;
-            } else
-                return super.call(receiver, args);
-        }
-
-        public Object call(Object receiver, Object arg1, Object arg2) throws Throwable {
-            if (checkPojoMetaClass()) {
-                try {
-                    final char[] objects = (char[]) receiver;
-                    objects[normaliseIndex((Integer) arg1, objects.length)] = (Character) arg2;
-                    return null;
-                }
-                catch (ClassCastException e) {
-                    if ((receiver instanceof char[]) && (arg1 instanceof Integer))
-                        throw e;
-                }
-            }
-            return super.call(receiver, arg1, arg2);
-        }
-    }
-}
+/*
+ *  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.runtime.dgmimpl.arrays;
+
+import groovy.lang.MetaClassImpl;
+import groovy.lang.MetaMethod;
+import org.codehaus.groovy.reflection.CachedClass;
+import org.codehaus.groovy.reflection.ReflectionCache;
+import org.codehaus.groovy.runtime.callsite.CallSite;
+import org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite;
+import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
+
+public class CharacterArrayPutAtMetaMethod extends ArrayPutAtMetaMethod {
+    private static final CachedClass OBJECT_CLASS = ReflectionCache.OBJECT_CLASS;
+    private static final CachedClass ARR_CLASS = ReflectionCache.getCachedClass(char[].class);
+    private static final CachedClass[] PARAM_CLASS_ARR = new CachedClass[]{INTEGER_CLASS, OBJECT_CLASS};
+
+    public CharacterArrayPutAtMetaMethod() {
+        parameterTypes = PARAM_CLASS_ARR;
+    }
+
+    public final CachedClass getDeclaringClass() {
+        return ARR_CLASS;
+    }
+
+    public Object invoke(Object object, Object[] args) {
+        final char[] objects = (char[]) object;
+        final int index = normaliseIndex((Integer) args[0], objects.length);
+        objects[index] = DefaultTypeTransformation.getCharFromSizeOneString(args[1]);
+        return null;
+    }
+
+    public CallSite createPojoCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) {
+        if (!(args[0] instanceof Integer) || !(args[1] instanceof Character))
+            return PojoMetaMethodSite.createNonAwareCallSite(site, metaClass, metaMethod, params, args);
+        else
+            return new MyPojoMetaMethodSite(site, metaClass, metaMethod, params);
+    }
+
+    private static class MyPojoMetaMethodSite extends PojoMetaMethodSite {
+        public MyPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params) {
+            super(site, metaClass, metaMethod, params);
+        }
+
+        public Object call(Object receiver, Object[] args) throws Throwable {
+            if ((receiver instanceof char[] && args[0] instanceof Integer && args[1] instanceof Character)
+                    && checkPojoMetaClass()) {
+                final char[] objects = (char[]) receiver;
+                objects[normaliseIndex((Integer) args[0], objects.length)] = (Character) args[1];
+                return null;
+            } else
+                return super.call(receiver, args);
+        }
+
+        public Object call(Object receiver, Object arg1, Object arg2) throws Throwable {
+            if (checkPojoMetaClass()) {
+                try {
+                    final char[] objects = (char[]) receiver;
+                    objects[normaliseIndex((Integer) arg1, objects.length)] = (Character) arg2;
+                    return null;
+                }
+                catch (ClassCastException e) {
+                    if ((receiver instanceof char[]) && (arg1 instanceof Integer))
+                        throw e;
+                }
+            }
+            return super.call(receiver, arg1, arg2);
+        }
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/ObjectArrayPutAtMetaMethod.java b/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/ObjectArrayPutAtMetaMethod.java
index 28e51ba..3db454d 100644
--- a/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/ObjectArrayPutAtMetaMethod.java
+++ b/src/main/java/org/codehaus/groovy/runtime/dgmimpl/arrays/ObjectArrayPutAtMetaMethod.java
@@ -1,97 +1,97 @@
-/*
- *  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.runtime.dgmimpl.arrays;
-
-import groovy.lang.GString;
-import groovy.lang.MetaClassImpl;
-import groovy.lang.MetaMethod;
-import org.codehaus.groovy.reflection.CachedClass;
-import org.codehaus.groovy.reflection.ReflectionCache;
-import org.codehaus.groovy.runtime.callsite.CallSite;
-import org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite;
-import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
-
-public class ObjectArrayPutAtMetaMethod extends ArrayPutAtMetaMethod {
-    private static final CachedClass OBJECT_CLASS = ReflectionCache.getCachedClass(Object.class);
-    private static final CachedClass OBJECT_ARR_CLASS = ReflectionCache.OBJECT_ARRAY_CLASS;
-    private static final CachedClass[] PARAM_CLASS_ARR = new CachedClass[]{INTEGER_CLASS, OBJECT_CLASS};
-
-    public ObjectArrayPutAtMetaMethod() {
-        parameterTypes = PARAM_CLASS_ARR;
-    }
-
-    public final CachedClass getDeclaringClass() {
-        return OBJECT_ARR_CLASS;
-    }
-
-    public Object invoke(Object object, Object[] arguments) {
-        final Object[] objects = (Object[]) object;
-        final int index = normaliseIndex((Integer) arguments[0], objects.length);
-        objects[index] = adjustNewValue(objects, arguments[1]);
-        return null;
-    }
-
-    private static Object adjustNewValue(Object[] objects, Object newValue) {
-        Class arrayComponentClass = objects.getClass().getComponentType();
-        Object adjustedNewVal = newValue;
-        if (newValue instanceof Number) {
-            if (!arrayComponentClass.equals(newValue.getClass())) {
-                adjustedNewVal = DefaultTypeTransformation.castToType(newValue, arrayComponentClass);
-            }
-        } else if (Character.class.isAssignableFrom(arrayComponentClass)) {
-            adjustedNewVal = DefaultTypeTransformation.getCharFromSizeOneString(newValue);
-        } else if (Number.class.isAssignableFrom(arrayComponentClass)) {
-            if (newValue instanceof Character || newValue instanceof String || newValue instanceof GString) {
-                Character ch = DefaultTypeTransformation.getCharFromSizeOneString(newValue);
-                adjustedNewVal = DefaultTypeTransformation.castToType(ch, arrayComponentClass);
-            }
-        } else if (arrayComponentClass.isArray()) {
-            adjustedNewVal = DefaultTypeTransformation.castToType(newValue, arrayComponentClass);
-        }
-        return adjustedNewVal;
-    }
-
-    public CallSite createPojoCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) {
-        if (!(args[0] instanceof Integer))
-            return PojoMetaMethodSite.createNonAwareCallSite(site, metaClass, metaMethod, params, args);
-        else
-            return new MyPojoMetaMethodSite(site, metaClass, metaMethod, params);
-    }
-
-    private static class MyPojoMetaMethodSite extends PojoMetaMethodSite {
-        public MyPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params) {
-            super(site, metaClass, metaMethod, params);
-        }
-
-        public Object call(Object receiver, Object arg1, Object arg2) throws Throwable {
-            if (checkPojoMetaClass()) {
-                try {
-                    final Object[] objects = (Object[]) receiver;
-                    objects[normaliseIndex((Integer) arg1, objects.length)] = adjustNewValue(objects, arg2);
-                    return null;
-                }
-                catch (ClassCastException e) {
-                    if ((receiver instanceof Object[]) && (arg1 instanceof Integer))
-                        throw e;
-                }
-            }
-            return super.call(receiver, arg1, arg2);
-        }
-    }
-}
+/*
+ *  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.runtime.dgmimpl.arrays;
+
+import groovy.lang.GString;
+import groovy.lang.MetaClassImpl;
+import groovy.lang.MetaMethod;
+import org.codehaus.groovy.reflection.CachedClass;
+import org.codehaus.groovy.reflection.ReflectionCache;
+import org.codehaus.groovy.runtime.callsite.CallSite;
+import org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite;
+import org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation;
+
+public class ObjectArrayPutAtMetaMethod extends ArrayPutAtMetaMethod {
+    private static final CachedClass OBJECT_CLASS = ReflectionCache.getCachedClass(Object.class);
+    private static final CachedClass OBJECT_ARR_CLASS = ReflectionCache.OBJECT_ARRAY_CLASS;
+    private static final CachedClass[] PARAM_CLASS_ARR = new CachedClass[]{INTEGER_CLASS, OBJECT_CLASS};
+
+    public ObjectArrayPutAtMetaMethod() {
+        parameterTypes = PARAM_CLASS_ARR;
+    }
+
+    public final CachedClass getDeclaringClass() {
+        return OBJECT_ARR_CLASS;
+    }
+
+    public Object invoke(Object object, Object[] arguments) {
+        final Object[] objects = (Object[]) object;
+        final int index = normaliseIndex((Integer) arguments[0], objects.length);
+        objects[index] = adjustNewValue(objects, arguments[1]);
+        return null;
+    }
+
+    private static Object adjustNewValue(Object[] objects, Object newValue) {
+        Class arrayComponentClass = objects.getClass().getComponentType();
+        Object adjustedNewVal = newValue;
+        if (newValue instanceof Number) {
+            if (!arrayComponentClass.equals(newValue.getClass())) {
+                adjustedNewVal = DefaultTypeTransformation.castToType(newValue, arrayComponentClass);
+            }
+        } else if (Character.class.isAssignableFrom(arrayComponentClass)) {
+            adjustedNewVal = DefaultTypeTransformation.getCharFromSizeOneString(newValue);
+        } else if (Number.class.isAssignableFrom(arrayComponentClass)) {
+            if (newValue instanceof Character || newValue instanceof String || newValue instanceof GString) {
+                Character ch = DefaultTypeTransformation.getCharFromSizeOneString(newValue);
+                adjustedNewVal = DefaultTypeTransformation.castToType(ch, arrayComponentClass);
+            }
+        } else if (arrayComponentClass.isArray()) {
+            adjustedNewVal = DefaultTypeTransformation.castToType(newValue, arrayComponentClass);
+        }
+        return adjustedNewVal;
+    }
+
+    public CallSite createPojoCallSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params, Object receiver, Object[] args) {
+        if (!(args[0] instanceof Integer))
+            return PojoMetaMethodSite.createNonAwareCallSite(site, metaClass, metaMethod, params, args);
+        else
+            return new MyPojoMetaMethodSite(site, metaClass, metaMethod, params);
+    }
+
+    private static class MyPojoMetaMethodSite extends PojoMetaMethodSite {
+        public MyPojoMetaMethodSite(CallSite site, MetaClassImpl metaClass, MetaMethod metaMethod, Class[] params) {
+            super(site, metaClass, metaMethod, params);
+        }
+
+        public Object call(Object receiver, Object arg1, Object arg2) throws Throwable {
+            if (checkPojoMetaClass()) {
+                try {
+                    final Object[] objects = (Object[]) receiver;
+                    objects[normaliseIndex((Integer) arg1, objects.length)] = adjustNewValue(objects, arg2);
+                    return null;
+                }
+                catch (ClassCastException e) {
+                    if ((receiver instanceof Object[]) && (arg1 instanceof Integer))
+                        throw e;
+                }
+            }
+            return super.call(receiver, arg1, arg2);
+        }
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/metaclass/ConcurrentReaderHashMap.java b/src/main/java/org/codehaus/groovy/runtime/metaclass/ConcurrentReaderHashMap.java
index ef7da8f..560cf97 100644
--- a/src/main/java/org/codehaus/groovy/runtime/metaclass/ConcurrentReaderHashMap.java
+++ b/src/main/java/org/codehaus/groovy/runtime/metaclass/ConcurrentReaderHashMap.java
@@ -1,1271 +1,1271 @@
-/*
- *  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.runtime.metaclass;
-
-import java.io.IOException;
-import java.io.Serializable;
-import java.util.AbstractCollection;
-import java.util.AbstractMap;
-import java.util.AbstractSet;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Enumeration;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.NoSuchElementException;
-import java.util.Set;
-
-/**
- * A hash table that supports mostly-concurrent reading, but
- * exclusive writing.  Because reads are not limited to periods
- * without writes, a concurrent reader policy is weaker than a classic
- * reader/writer policy, but is generally faster and allows more
- * concurrency. This class is a good choice especially for tables that
- * are mainly created by one thread during the start-up phase of a
- * program, and from then on, are mainly read (with perhaps occasional
- * additions or removals) in many threads.  If you also need concurrency
- * among writes, consider instead using ConcurrentHashMap.
- * <p>
- *
- * Successful retrievals using get(key) and containsKey(key) usually
- * run without locking. Unsuccessful ones (i.e., when the key is not
- * present) do involve brief synchronization (locking).  Also, the
- * size and isEmpty methods are always synchronized.
- *
- * <p> Because retrieval operations can ordinarily overlap with
- * writing operations (i.e., put, remove, and their derivatives),
- * retrievals can only be guaranteed to return the results of the most
- * recently <em>completed</em> operations holding upon their
- * onset. Retrieval operations may or may not return results
- * reflecting in-progress writing operations.  However, the retrieval
- * operations do always return consistent results -- either those
- * holding before any single modification or after it, but never a
- * nonsense result.  For aggregate operations such as putAll and
- * clear, concurrent reads may reflect insertion or removal of only
- * some entries. In those rare contexts in which you use a hash table
- * to synchronize operations across threads (for example, to prevent
- * reads until after clears), you should either encase operations
- * in synchronized blocks, or instead use java.util.Hashtable.
- *
- * <p>
- *
- * This class also supports optional guaranteed
- * exclusive reads, simply by surrounding a call within a synchronized
- * block, as in <br> 
- * <code>ConcurrentReaderHashMap t; ... Object v; <br>
- * synchronized(t) { v = t.get(k); } </code> <br>
- *
- * But this is not usually necessary in practice. For
- * example, it is generally inefficient to write:
- *
- * <pre>
- *   ConcurrentReaderHashMap t; ...            // Inefficient version
- *   Object key; ...
- *   Object value; ...
- *   synchronized(t) { 
- *     if (!t.containsKey(key))
- *       t.put(key, value);
- *       // other code if not previously present
- *     }
- *     else {
- *       // other code if it was previously present
- *     }
- *   }
- *</pre>
- * Instead, if the values are intended to be the same in each case, just take advantage of the fact that put returns
- * null if the key was not previously present:
- * <pre>
- *   ConcurrentReaderHashMap t; ...                // Use this instead
- *   Object key; ...
- *   Object value; ...
- *   Object oldValue = t.put(key, value);
- *   if (oldValue == null) {
- *     // other code if not previously present
- *   }
- *   else {
- *     // other code if it was previously present
- *   }
- *</pre>
- * <p>
- *
- * Iterators and Enumerations (i.e., those returned by
- * keySet().iterator(), entrySet().iterator(), values().iterator(),
- * keys(), and elements()) return elements reflecting the state of the
- * hash table at some point at or since the creation of the
- * iterator/enumeration.  They will return at most one instance of
- * each element (via next()/nextElement()), but might or might not
- * reflect puts and removes that have been processed since they were
- * created.  They do <em>not</em> throw ConcurrentModificationException.
- * However, these iterators are designed to be used by only one
- * thread at a time. Sharing an iterator across multiple threads may
- * lead to unpredictable results if the table is being concurrently
- * modified.  Again, you can ensure interference-free iteration by
- * enclosing the iteration in a synchronized block.  <p>
- *
- * This class may be used as a direct replacement for any use of
- * java.util.Hashtable that does not depend on readers being blocked
- * during updates. Like Hashtable but unlike java.util.HashMap,
- * this class does NOT allow <tt>null</tt> to be used as a key or
- * value.  This class is also typically faster than ConcurrentHashMap
- * when there is usually only one thread updating the table, but 
- * possibly many retrieving values from it.
- * <p>
- *
- * Implementation note: A slightly faster implementation of
- * this class will be possible once planned Java Memory Model
- * revisions are in place.
- *
- * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
- *
- * @author Adapted from ConcurrentHashMap (Doug Lea)
- * @author adapted by the Groovy community
- */
-public class ConcurrentReaderHashMap 
-  extends AbstractMap 
-  implements Cloneable, Serializable {
-  private static final long serialVersionUID = -3225682440765612861L;
-
-
-  /*
-    The basic strategy is an optimistic-style scheme based on
-    the guarantee that the hash table and its lists are always
-    kept in a consistent enough state to be read without locking:
-
-    * Read operations first proceed without locking, by traversing the
-       apparently correct list of the apparently correct bin. If an
-       entry is found, but not invalidated (value field null), it is
-       returned. If not found, operations must recheck (after a memory
-       barrier) to make sure they are using both the right list and
-       the right table (which can change under re-sizes). If
-       invalidated, reads must acquire main update lock to wait out
-       the update, and then re-traverse.
-
-    * All list additions are at the front of each bin, making it easy
-       to check changes, and also fast to traverse.  Entry next
-       pointers are never assigned. Remove() builds new nodes when
-       necessary to preserve this.
-
-    * Remove() (also clear()) invalidates removed nodes to alert read
-       operations that they must wait out the full modifications.
-  */
-
-  /** A Serializable class for barrier lock **/
-  protected static class BarrierLock implements java.io.Serializable {
-      private static final long serialVersionUID = -2159505361622844863L;
-  }
-
-  /**
-   * Lock used only for its memory effects.
-   **/
-  protected final BarrierLock barrierLock = new BarrierLock();
-
-  /**
-   * field written to only to guarantee lock ordering.
-   **/
-  protected transient Object lastWrite;
-
-  /**
-   * Force a memory synchronization that will cause
-   * all readers to see table. Call only when already
-   * holding main sync lock.
-   **/
-  protected final void recordModification(Object x) { 
-    synchronized(barrierLock) {
-      lastWrite = x;
-    }
-  }
-
-  /**
-   * Get ref to table; the reference and the cells it
-   * accesses will be at least as fresh as from last
-   * use of barrierLock
-   **/
-  protected final Entry[] getTableForReading() { 
-    synchronized(barrierLock) {
-      return table; 
-    }
-  }
-
-
-  /**
-   * The default initial number of table slots for this table (32).
-   * Used when not otherwise specified in constructor.
-   **/
-  public static final int DEFAULT_INITIAL_CAPACITY = 32; 
-
-
-  /**
-   * The minimum capacity, used if a lower value is implicitly specified
-   * by either of the constructors with arguments.  
-   * MUST be a power of two.
-   */
-  private static final int MINIMUM_CAPACITY = 4;
-  
-  /**
-   * The maximum capacity, used if a higher value is implicitly specified
-   * by either of the constructors with arguments.
-   * MUST be a power of two &lt;= 1&lt;&lt;30.
-   */
-  private static final int MAXIMUM_CAPACITY = 1 << 30;
-  
-  /**
-   * The default load factor for this table (1.0).
-   * Used when not otherwise specified in constructor.
-   **/
-
-  public static final float DEFAULT_LOAD_FACTOR = 0.75f; 
-
-
-  /**
-   * The hash table data.
-   */
-  protected transient Entry[] table;
-
-  /**
-   * The total number of mappings in the hash table.
-   */
-  protected transient int count;
-
-  /**
-   * The table is rehashed when its size exceeds this threshold.  (The
-   * value of this field is always (int)(capacity * loadFactor).)
-   *
-   * @serial
-   */
-  protected int threshold;
-
-  /**
-   * The load factor for the hash table.
-   *
-   * @serial
-   */
-  protected float loadFactor;
-
-  /**
-   * Returns the appropriate capacity (power of two) for the specified 
-   * initial capacity argument.
-   */
-  private static int p2capacity(int initialCapacity) {
-    int cap = initialCapacity;
-    
-    // Compute the appropriate capacity
-    int result;
-    if (cap > MAXIMUM_CAPACITY || cap < 0) {
-      result = MAXIMUM_CAPACITY;
-    } else {
-      result = MINIMUM_CAPACITY;
-      while (result < cap)
-        result <<= 1;
-    }
-    return result;
-  }
-
-  /**
-   * Return hash code for Object x. Since we are using power-of-two
-   * tables, it is worth the effort to improve hashcode via
-   * the same multiplicative scheme as used in IdentityHashMap.
-   */
-  private static int hash(Object x) {
-    int h = x.hashCode();
-    // Multiply by 127 (quickly, via shifts), and mix in some high
-    // bits to help guard against bunching of codes that are
-    // consecutive or equally spaced.
-    return ((h << 7) - h + (h >>> 9) + (h >>> 17));
-  }
-
-  /** 
-   * Check for equality of non-null references x and y. 
-   **/
-  protected boolean eq(Object x, Object y) {
-    return x == y || x.equals(y);
-  }
-
-  /**
-   * Constructs a new, empty map with the specified initial 
-   * capacity and the specified load factor. 
-   *
-   * @param initialCapacity the initial capacity
-   *  The actual initial capacity is rounded to the nearest power of two.
-   * @param loadFactor  the load factor of the ConcurrentReaderHashMap
-   * @throws IllegalArgumentException  if the initial maximum number 
-   *               of elements is less
-   *               than zero, or if the load factor is non-positive.
-   */
-  public ConcurrentReaderHashMap(int initialCapacity, float loadFactor) {
-    if (loadFactor <= 0)
-      throw new IllegalArgumentException("Illegal Load factor: "+
-                                         loadFactor);
-    this.loadFactor = loadFactor;
-
-    int cap = p2capacity(initialCapacity);
-
-    table = new Entry[cap];
-    threshold = (int)(cap * loadFactor);
-  }
-
-  /**
-   * Constructs a new, empty map with the specified initial 
-   * capacity and default load factor.
-   *
-   * @param   initialCapacity   the initial capacity of the 
-   *                            ConcurrentReaderHashMap.
-   * @throws    IllegalArgumentException if the initial maximum number 
-   *              of elements is less than zero.
-   */
-  public ConcurrentReaderHashMap(int initialCapacity) {
-    this(initialCapacity, DEFAULT_LOAD_FACTOR);
-  }
-
-  /**
-   * Constructs a new, empty map with a default initial capacity
-   * and load factor.
-   */
-  public ConcurrentReaderHashMap() {
-    this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
-  }
-
-  /**
-   * Constructs a new map with the same mappings as the given map.  The
-   * map is created with a capacity of twice the number of mappings in
-   * the given map or 16 (whichever is greater), and a default load factor.
-   */
-  public ConcurrentReaderHashMap(Map t) {
-        this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1, 16),
-             DEFAULT_LOAD_FACTOR);
-    putAll(t);
-  }
-
-  /**
-   * Returns the number of key-value mappings in this map.
-   *
-   * @return the number of key-value mappings in this map.
-   */
-  public synchronized int size() {
-    return count;
-  }
-
-  /**
-   * Returns <tt>true</tt> if this map contains no key-value mappings.
-   *
-   * @return <tt>true</tt> if this map contains no key-value mappings.
-   */
-  public synchronized boolean isEmpty() {
-    return count == 0;
-  }
-  
-
-
-  /**
-   * Returns the value to which the specified key is mapped in this table.
-   *
-   * @param   key   a key in the table.
-   * @return  the value to which the key is mapped in this table;
-   *          <code>null</code> if the key is not mapped to any value in
-   *          this table.
-   * @exception  NullPointerException  if the key is <code>null</code>.
-   * @see     #put(Object, Object)
-   */
-  public Object get(Object key) {
-
-    // throw null pointer exception if key null
-    int hash = hash(key);
-
-    /* 
-       Start off at the apparently correct bin.  If entry is found, we
-       need to check after a barrier anyway.  If not found, we need a
-       barrier to check if we are actually in right bin. So either
-       way, we encounter only one barrier unless we need to retry.
-       And we only need to fully synchronize if there have been
-       concurrent modifications.
-    */
-
-    Entry[] tab = table;
-    int index = hash & (tab.length - 1);
-    Entry first = tab[index];
-    Entry e = first;
-
-    for (;;) {
-      if (e == null) {
-
-        // If key apparently not there, check to
-        // make sure this was a valid read
-
-        Entry[] reread = getTableForReading();
-        if (tab == reread && first == tab[index])
-          return null;
-        else {
-          // Wrong list -- must restart traversal at new first
-          tab = reread;
-          e = first = tab[index = hash & (tab.length-1)];
-        }
-
-      }
-
-      else if (e.hash == hash && eq(key, e.key)) {
-        Object value = e.value;
-        if (value != null) 
-          return value;
-
-        // Entry was invalidated during deletion. But it could
-        // have been re-inserted, so we must re-traverse.
-        // To avoid useless contention, get lock to wait out modifications
-        // before re-traversing.
-
-        synchronized(this) {
-          tab = table;
-        }
-        e = first = tab[index = hash & (tab.length-1)];
-
-      }
-      else
-        e = e.next;
-    }
-  }
-
-
-  /**
-   * Tests if the specified object is a key in this table.
-   * 
-   * @param   key   possible key.
-   * @return  <code>true</code> if and only if the specified object 
-   *          is a key in this table, as determined by the 
-   *          <tt>equals</tt> method; <code>false</code> otherwise.
-   * @exception  NullPointerException  if the key is <code>null</code>.
-   * @see     #contains(Object)
-   */
-  public boolean containsKey(Object key) {
-    return get(key) != null;
-  }
-
-  /**
-   * Maps the specified <code>key</code> to the specified 
-   * <code>value</code> in this table. Neither the key nor the 
-   * value can be <code>null</code>. <p>
-   *
-   * The value can be retrieved by calling the <code>get</code> method 
-   * with a key that is equal to the original key. 
-   *
-   * @param      key     the table key.
-   * @param      value   the value.
-   * @return     the previous value of the specified key in this table,
-   *             or <code>null</code> if it did not have one.
-   * @exception  NullPointerException  if the key or value is <code>null</code>.
-   * @see     Object#equals(Object)
-   * @see     #get(Object)
-   */
-  public Object put(Object key, Object value) {
-    if (value == null) 
-      throw new NullPointerException();
-    
-    int hash = hash(key);
-    Entry[] tab = table;
-    int index = hash & (tab.length-1);
-    Entry first = tab[index];
-    Entry e;
-
-    for (e = first; e != null; e = e.next)
-      if (e.hash == hash && eq(key, e.key))
-        break;
-
-    synchronized(this) {
-      if (tab == table) {
-        if (e == null) {
-          //  make sure we are adding to correct list
-          if (first == tab[index]) {
-            //  Add to front of list
-            Entry newEntry = new Entry(hash, key, value, first);
-            tab[index] = newEntry;
-            if (++count >= threshold) rehash();
-            else recordModification(newEntry);
-            return null;
-          }
-        }
-        else {
-          Object oldValue = e.value; 
-          if (first == tab[index] && oldValue != null) {
-            e.value = value;
-            return oldValue;
-          }
-        }
-      }
-      
-      // retry if wrong list or lost race against concurrent remove
-      return sput(key, value, hash);
-    }
-  }
-
-
-  /**
-   * Continuation of put(), called only when sync lock is
-   * held and interference has been detected.
-   **/
-  protected Object sput(Object key, Object value, int hash) { 
-
-    Entry[] tab = table;
-    int index = hash & (tab.length-1);
-    Entry first = tab[index];
-    Entry e = first;
-
-    for (;;) {
-      if (e == null) {
-        Entry newEntry = new Entry(hash, key, value, first);
-        tab[index] = newEntry;
-        if (++count >= threshold) rehash();
-        else recordModification(newEntry);
-        return null;
-      }
-      else if (e.hash == hash && eq(key, e.key)) {
-        Object oldValue = e.value; 
-        e.value = value;
-        return oldValue;
-      }
-      else
-        e = e.next;
-    }
-  }
-
-
-  /**
-   * Rehashes the contents of this map into a new table
-   * with a larger capacity. This method is called automatically when the
-   * number of keys in this map exceeds its capacity and load factor.
-   */
-  protected void rehash() { 
-    Entry[] oldTable = table;
-    int oldCapacity = oldTable.length;
-    if (oldCapacity >= MAXIMUM_CAPACITY) {
-      threshold = Integer.MAX_VALUE; // avoid re-triggering
-      return;
-    }
-
-    int newCapacity = oldCapacity << 1;
-    int mask = newCapacity - 1;
-    threshold = (int)(newCapacity * loadFactor);
-
-    Entry[] newTable = new Entry[newCapacity];
-    /*
-     * Reclassify nodes in each list to new Map.  Because we are
-     * using power-of-two expansion, the elements from each bin
-     * must either stay at same index, or move to
-     * oldCapacity+index. We also eliminate unnecessary node
-     * creation by catching cases where old nodes can be reused
-     * because their next fields won't change. Statistically, at
-     * the default threshold, only about one-sixth of them need
-     * cloning. (The nodes they replace will be garbage
-     * collectible as soon as they are no longer referenced by any
-     * reader thread that may be in the midst of traversing table
-     * right now.)
-     */
-    
-    for (int i = 0; i < oldCapacity ; i++) {
-      // We need to guarantee that any existing reads of old Map can
-      // proceed. So we cannot yet null out each bin.
-      Entry e = oldTable[i];
-      
-      if (e != null) {
-        int idx = e.hash & mask;
-        Entry next = e.next;
-        
-        //  Single node on list
-        if (next == null) 
-          newTable[idx] = e;
-        
-        else {    
-          // Reuse trailing consecutive sequence of all same bit
-          Entry lastRun = e;
-          int lastIdx = idx;
-          for (Entry last = next; last != null; last = last.next) {
-            int k = last.hash & mask;
-            if (k != lastIdx) {
-              lastIdx = k;
-              lastRun = last;
-            }
-          }
-          newTable[lastIdx] = lastRun;
-          
-          // Clone all remaining nodes
-          for (Entry p = e; p != lastRun; p = p.next) {
-            int k = p.hash & mask;
-            newTable[k] = new Entry(p.hash, p.key, 
-                                    p.value, newTable[k]);
-          }
-        }
-      }
-    }
-
-    table = newTable;
-    recordModification(newTable);
-  }
-
-  /**
-   * Removes the key (and its corresponding value) from this 
-   * table. This method does nothing if the key is not in the table.
-   *
-   * @param   key   the key that needs to be removed.
-   * @return  the value to which the key had been mapped in this table,
-   *          or <code>null</code> if the key did not have a mapping.
-   * @exception  NullPointerException  if the key is
-   *               <code>null</code>.
-   */
-  public Object remove(Object key) {
-    /*
-      Find the entry, then 
-        1. Set value field to null, to force get() to retry
-        2. Rebuild the list without this entry.
-           All entries following removed node can stay in list, but
-           all preceding ones need to be cloned.  Traversals rely
-           on this strategy to ensure that elements will not be
-          repeated during iteration.
-    */
-          
-
-    int hash = hash(key);
-    Entry[] tab = table;
-    int index = hash & (tab.length-1);
-    Entry first = tab[index];
-    Entry e = first;
-      
-    for (e = first; e != null; e = e.next) 
-      if (e.hash == hash && eq(key, e.key)) 
-        break;
-
-
-    synchronized(this) {
-      if (tab == table) {
-        if (e == null) {
-          if (first == tab[index])
-            return null;
-        }
-        else {
-          Object oldValue = e.value;
-          if (first == tab[index] && oldValue != null) {
-            e.value = null;
-            count--;
-            
-            Entry head = e.next;
-            for (Entry p = first; p != e; p = p.next) 
-              head = new Entry(p.hash, p.key, p.value, head);
-            
-            tab[index] = head;
-            recordModification(head);
-            return oldValue;
-          }
-        }
-      }
-    
-      // Wrong list or interference
-      return sremove(key, hash);
-    }
-  }
-
-  /**
-   * Continuation of remove(), called only when sync lock is
-   * held and interference has been detected.
-   **/
-  protected Object sremove(Object key, int hash) {
-    Entry[] tab = table;
-    int index = hash & (tab.length-1);
-    Entry first = tab[index];
-      
-    for (Entry e = first; e != null; e = e.next) {
-      if (e.hash == hash && eq(key, e.key)) {
-        Object oldValue = e.value;
-        e.value = null;
-        count--;
-        Entry head = e.next;
-        for (Entry p = first; p != e; p = p.next) 
-          head = new Entry(p.hash, p.key, p.value, head);
-        
-        tab[index] = head;
-        recordModification(head);
-        return oldValue;
-      }
-    }
-    return null;
-  }
-
-
-  /**
-   * Returns <tt>true</tt> if this map maps one or more keys to the
-   * specified value. Note: This method requires a full internal
-   * traversal of the hash table, and so is much slower than
-   * method <tt>containsKey</tt>.
-   *
-   * @param value value whose presence in this map is to be tested.
-   * @return <tt>true</tt> if this map maps one or more keys to the
-   * specified value.  
-   * @exception  NullPointerException  if the value is <code>null</code>.
-   */
-  public boolean containsValue(Object value) {
-    if (value == null) throw new NullPointerException();
-
-    Entry tab[] = getTableForReading();
-    
-    for (int i = 0 ; i < tab.length; ++i) {
-      for (Entry e = tab[i] ; e != null ; e = e.next) 
-        if (value.equals(e.value))
-          return true;
-    }
-
-    return false;
-  }
-
-  /**
-   * Tests if some key maps into the specified value in this table.
-   * This operation is more expensive than the <code>containsKey</code>
-   * method.<p>
-   *
-   * Note that this method is identical in functionality to containsValue,
-   * (which is part of the Map interface in the collections framework).
-   * 
-   * @param      value   a value to search for.
-   * @return     <code>true</code> if and only if some key maps to the
-   *             <code>value</code> argument in this table as 
-   *             determined by the <tt>equals</tt> method;
-   *             <code>false</code> otherwise.
-   * @exception  NullPointerException  if the value is <code>null</code>.
-   * @see        #containsKey(Object)
-   * @see        #containsValue(Object)
-   * @see      Map
-   */
-  public boolean contains(Object value) {
-    return containsValue(value);
-  }
-
-
-  /**
-   * Copies all of the mappings from the specified map to this one.
-   * 
-   * These mappings replace any mappings that this map had for any of the
-   * keys currently in the specified Map.
-   *
-   * @param t Mappings to be stored in this map.
-   */
-  public synchronized void putAll(Map t) {
-    int n = t.size();
-    if (n == 0)
-      return;
-
-    // Expand enough to hold at least n elements without resizing.
-    // We can only resize table by factor of two at a time.
-    // It is faster to rehash with fewer elements, so do it now.
-    while (n >= threshold)
-      rehash();
-
-    for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
-      Map.Entry entry = (Map.Entry) it.next();
-      Object key = entry.getKey();
-      Object value = entry.getValue();
-      put(key, value);
-    }
-  }
-
-
-  /**
-   * Removes all mappings from this map.
-   */
-  public synchronized void clear() {
-    Entry tab[] = table;
-    for (int i = 0; i < tab.length ; ++i) { 
-
-      // must invalidate all to force concurrent get's to wait and then retry
-      for (Entry e = tab[i]; e != null; e = e.next) 
-        e.value = null; 
-
-      tab[i] = null;
-    }
-    count = 0;
-    recordModification(tab);
-  }
-
-  /**
-   * Returns a shallow copy of this 
-   * <tt>ConcurrentReaderHashMap</tt> instance: the keys and
-   * values themselves are not cloned.
-   *
-   * @return a shallow copy of this map.
-   */
-  public synchronized Object clone() {
-    try { 
-      ConcurrentReaderHashMap t = (ConcurrentReaderHashMap)super.clone();
-
-      t.keySet = null;
-      t.entrySet = null;
-      t.values = null;
-
-      Entry[] tab = table;
-      t.table = new Entry[tab.length];
-      Entry[] ttab = t.table;
-
-      for (int i = 0; i < tab.length; ++i) {
-        Entry first = null;
-        for (Entry e = tab[i]; e != null; e = e.next) 
-          first = new Entry(e.hash, e.key, e.value, first);
-        ttab[i] = first;
-      }
-
-      return t;
-    } 
-    catch (CloneNotSupportedException e) { 
-      // this shouldn't happen, since we are Cloneable
-      throw new InternalError();
-    }
-  }
-
-  // Views
-
-  protected transient Set keySet = null;
-  protected transient Set entrySet = null;
-  protected transient Collection values = null;
-
-  /**
-   * Returns a set view of the keys contained in this map.  The set is
-   * backed by the map, so changes to the map are reflected in the set, and
-   * vice-versa.  The set supports element removal, which removes the
-   * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
-   * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
-   * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
-   * <tt>addAll</tt> operations.
-   *
-   * @return a set view of the keys contained in this map.
-   */
-  public Set keySet() {
-    Set ks = keySet;
-    return (ks != null)? ks : (keySet = new KeySet());
-  }
-  
-  private class KeySet extends AbstractSet {
-    public Iterator iterator() {
-      return new KeyIterator();
-    }
-    public int size() {
-      return ConcurrentReaderHashMap.this.size();
-    }
-    public boolean contains(Object o) {
-      return ConcurrentReaderHashMap.this.containsKey(o);
-    }
-    public boolean remove(Object o) {
-      return ConcurrentReaderHashMap.this.remove(o) != null;
-    }
-    public void clear() {
-      ConcurrentReaderHashMap.this.clear();
-    }
-    public Object[] toArray() {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray();
-    }
-    public Object[] toArray(Object[] a) {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray(a);
-    }
-  }
-
-  /**
-   * Returns a collection view of the values contained in this map.  The
-   * collection is backed by the map, so changes to the map are reflected in
-   * the collection, and vice-versa.  The collection supports element
-   * removal, which removes the corresponding mapping from this map, via the
-   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
-   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
-   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
-   *
-   * @return a collection view of the values contained in this map.
-   */
-  public Collection values() {
-    Collection vs = values;
-    return (vs != null)? vs : (values = new Values());
-  }
-  
-  private class Values extends AbstractCollection {
-    public Iterator iterator() {
-      return new ValueIterator();
-    }
-    public int size() {
-      return ConcurrentReaderHashMap.this.size();
-    }
-    public boolean contains(Object o) {
-      return ConcurrentReaderHashMap.this.containsValue(o);
-    }
-    public void clear() {
-      ConcurrentReaderHashMap.this.clear();
-    }
-    public Object[] toArray() {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray();
-    }
-    public Object[] toArray(Object[] a) {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray(a);
-    }
-  }
-
-  /**
-   * Returns a collection view of the mappings contained in this map.  Each
-   * element in the returned collection is a <tt>Map.Entry</tt>.  The
-   * collection is backed by the map, so changes to the map are reflected in
-   * the collection, and vice-versa.  The collection supports element
-   * removal, which removes the corresponding mapping from the map, via the
-   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
-   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
-   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
-   *
-   * @return a collection view of the mappings contained in this map.
-   */
-  public Set entrySet() {
-    Set es = entrySet;
-    return (es != null) ? es : (entrySet = new EntrySet());
-  }
-
-  private class EntrySet extends AbstractSet {
-    public Iterator iterator() {
-      return new HashIterator();
-    }
-    public boolean contains(Object o) {
-      if (!(o instanceof Map.Entry))
-        return false;
-      Map.Entry entry = (Map.Entry)o;
-      Object v = ConcurrentReaderHashMap.this.get(entry.getKey());
-      return v != null && v.equals(entry.getValue());
-    }
-    public boolean remove(Object o) {
-      if (!(o instanceof Map.Entry))
-        return false;
-      return ConcurrentReaderHashMap.this.findAndRemoveEntry((Map.Entry)o);
-    }
-    public int size() {
-      return ConcurrentReaderHashMap.this.size();
-    }
-    public void clear() {
-      ConcurrentReaderHashMap.this.clear();
-    }
-    public Object[] toArray() {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray();
-    }
-    public Object[] toArray(Object[] a) {
-      Collection c = new ArrayList();
-      for (Iterator i = iterator(); i.hasNext(); )
-          c.add(i.next());
-      return c.toArray(a);
-    }
-  }
-
-  /**
-   * Helper method for entrySet.remove
-   **/
-  protected synchronized boolean findAndRemoveEntry(Map.Entry entry) {
-    Object key = entry.getKey();
-    Object v = get(key);
-    if (v != null && v.equals(entry.getValue())) {
-      remove(key);
-      return true;
-    }
-    else
-      return false;
-  }
-
-  /**
-   * Returns an enumeration of the keys in this table.
-   *
-   * @return  an enumeration of the keys in this table.
-   * @see     Enumeration
-   * @see     #elements()
-   * @see   #keySet()
-   * @see   Map
-   */
-  public Enumeration keys() {
-    return new KeyIterator();
-  }
-
-  /**
-   * Returns an enumeration of the values in this table.
-   * Use the Enumeration methods on the returned object to fetch the elements
-   * sequentially.
-   *
-   * @return  an enumeration of the values in this table.
-   * @see     java.util.Enumeration
-   * @see     #keys()
-   * @see   #values()
-   * @see   Map
-   */
-  public Enumeration elements() {
-    return new ValueIterator();
-  }
-
-
-  /**
-   * ConcurrentReaderHashMap collision list entry.
-   */
-  protected static class Entry implements Map.Entry {
-
-    /* 
-       The use of volatile for value field ensures that
-       we can detect status changes without synchronization.
-       The other fields are never changed, and are
-       marked as final. 
-    */
-    protected final int hash;
-    protected final Object key;
-    protected final Entry next;
-    protected volatile Object value;
-
-    Entry(int hash, Object key, Object value, Entry next) {
-      this.hash = hash;
-      this.key = key;
-      this.next = next;
-      this.value = value;
-    }
-
-    // Map.Entry Ops 
-
-    public Object getKey() {
-      return key;
-    }
-
-    /**
-     * Get the value.  Note: In an entrySet or entrySet.iterator,
-     * unless the set or iterator is used under synchronization of the
-     * table as a whole (or you can otherwise guarantee lack of
-     * concurrent modification), <tt>getValue</tt> <em>might</em>
-     * return null, reflecting the fact that the entry has been
-     * concurrently removed. However, there are no assurances that
-     * concurrent removals will be reflected using this method.
-     * 
-     * @return     the current value, or null if the entry has been 
-     * detectably removed.
-     **/
-    public Object getValue() {
-      return value; 
-    }
-
-    /**
-     * Set the value of this entry.  Note: In an entrySet or
-     * entrySet.iterator), unless the set or iterator is used under
-     * synchronization of the table as a whole (or you can otherwise
-     * guarantee lack of concurrent modification), <tt>setValue</tt>
-     * is not strictly guaranteed to actually replace the value field
-     * obtained via the <tt>get</tt> operation of the underlying hash
-     * table in multi-threaded applications.  If iterator-wide
-     * synchronization is not used, and any other concurrent
-     * <tt>put</tt> or <tt>remove</tt> operations occur, sometimes
-     * even to <em>other</em> entries, then this change is not
-     * guaranteed to be reflected in the hash table. (It might, or it
-     * might not. There are no assurances either way.)
-     *
-     * @param      value   the new value.
-     * @return     the previous value, or null if entry has been detectably
-     * removed.
-     * @exception  NullPointerException  if the value is <code>null</code>.
-     * 
-     **/
-    public Object setValue(Object value) {
-      if (value == null)
-        throw new NullPointerException();
-      Object oldValue = this.value;
-      this.value = value;
-      return oldValue;
-    }
-
-    public boolean equals(Object o) {
-      if (!(o instanceof Map.Entry))
-        return false;
-      Map.Entry e = (Map.Entry)o;
-      return (key.equals(e.getKey()) && value.equals(e.getValue()));
-    }
-    
-    public int hashCode() {
-      return  key.hashCode() ^ value.hashCode();
-    }
-    
-    public String toString() {
-      return key + "=" + value;
-    }
-
-  }
-
-  protected class HashIterator implements Iterator, Enumeration {
-    protected final Entry[] tab;           // snapshot of table
-    protected int index;                   // current slot 
-    protected Entry entry = null;          // current node of slot
-    protected Object currentKey;           // key for current node
-    protected Object currentValue;         // value for current node
-    protected Entry lastReturned = null;   // last node returned by next
-
-    protected HashIterator() {
-      tab = ConcurrentReaderHashMap.this.getTableForReading();
-      index = tab.length - 1;
-    }
-
-    public boolean hasMoreElements() { return hasNext(); }
-    public Object nextElement() { return next(); }
-
-
-    public boolean hasNext() {
-
-      /*
-        currentKey and currentValue are set here to ensure that next()
-        returns normally if hasNext() returns true. This avoids
-        surprises especially when final element is removed during
-        traversal -- instead, we just ignore the removal during
-        current traversal.  
-      */
-
-      for (;;) {
-        if (entry != null) {
-          Object v = entry.value;
-          if (v != null) {
-            currentKey = entry.key;
-            currentValue = v;
-            return true;
-          }
-          else
-            entry = entry.next;
-        }
-
-        while (entry == null && index >= 0)
-          entry = tab[index--];
-
-        if (entry == null) {
-          currentKey = currentValue = null;
-          return false;
-        }
-      }
-    }
-
-    protected Object returnValueOfNext() { return entry; }
-
-    public Object next() {
-      if (currentKey == null && !hasNext())
-        throw new NoSuchElementException();
-
-      Object result = returnValueOfNext();
-      lastReturned = entry;
-      currentKey = currentValue = null;
-      entry = entry.next;
-      return result;
-    }
-
-    public void remove() {
-      if (lastReturned == null)
-        throw new IllegalStateException();
-      ConcurrentReaderHashMap.this.remove(lastReturned.key);
-      lastReturned = null;
-    }
-
-  }
-
-
-  protected class KeyIterator extends HashIterator {
-    protected Object returnValueOfNext() { return currentKey; }
-  }
-  
-  protected class ValueIterator extends HashIterator {
-    protected Object returnValueOfNext() { return currentValue; }
-  }
-  
-
-
-  /**
-   * Save the state of the <tt>ConcurrentReaderHashMap</tt> 
-   * instance to a stream (i.e.,
-   * serialize it).
-   *
-   * @param s the stream
-   * @serialData The <i>capacity</i> of the
-   * ConcurrentReaderHashMap (the length of the
-   * bucket array) is emitted (int), followed  by the
-   * <i>size</i> of the ConcurrentReaderHashMap (the number of key-value
-   * mappings), followed by the key (Object) and value (Object)
-   * for each key-value mapping represented by the ConcurrentReaderHashMap
-   * The key-value mappings are emitted in no particular order.
-   */
-  private synchronized void writeObject(java.io.ObjectOutputStream s)
-    throws IOException  {
-    // Write out the threshold, loadfactor, and any hidden stuff
-    s.defaultWriteObject();
-    
-    // Write out number of buckets
-    s.writeInt(table.length);
-    
-    // Write out size (number of Mappings)
-    s.writeInt(count);
-    
-    // Write out keys and values (alternating)
-    for (int index = table.length-1; index >= 0; index--) {
-      Entry entry = table[index];
-      
-      while (entry != null) {
-        s.writeObject(entry.key);
-        s.writeObject(entry.value);
-        entry = entry.next;
-      }
-    }
-  }
-
-  /**
-   * Reconstitute the <tt>ConcurrentReaderHashMap</tt> 
-   * instance from a stream (i.e.,
-   * deserialize it).
-   *
-   * @param s the stream
-   */
-  private synchronized void readObject(java.io.ObjectInputStream s)
-    throws IOException, ClassNotFoundException  {
-    // Read in the threshold, loadfactor, and any hidden stuff
-    s.defaultReadObject();
-
-    // Read in number of buckets and allocate the bucket array;
-    int numBuckets = s.readInt();
-    table = new Entry[numBuckets];
-    
-    // Read in size (number of Mappings)
-    int size = s.readInt();
-    
-    // Read the keys and values, and put the mappings in the table
-    for (int i=0; i<size; i++) {
-      Object key = s.readObject();
-      Object value = s.readObject();
-      put(key, value);
-    }
-  }
-  
-  /** 
-   * @return the number of slots in this table
-   **/
-  public synchronized int capacity() {
-    return table.length;
-  }
-
-  /** 
-   * @return the load factor
-   **/
-  public float loadFactor() {
-    return loadFactor;
-  }
-}
+/*
+ *  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.runtime.metaclass;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.AbstractMap;
+import java.util.AbstractSet;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
+/**
+ * A hash table that supports mostly-concurrent reading, but
+ * exclusive writing.  Because reads are not limited to periods
+ * without writes, a concurrent reader policy is weaker than a classic
+ * reader/writer policy, but is generally faster and allows more
+ * concurrency. This class is a good choice especially for tables that
+ * are mainly created by one thread during the start-up phase of a
+ * program, and from then on, are mainly read (with perhaps occasional
+ * additions or removals) in many threads.  If you also need concurrency
+ * among writes, consider instead using ConcurrentHashMap.
+ * <p>
+ *
+ * Successful retrievals using get(key) and containsKey(key) usually
+ * run without locking. Unsuccessful ones (i.e., when the key is not
+ * present) do involve brief synchronization (locking).  Also, the
+ * size and isEmpty methods are always synchronized.
+ *
+ * <p> Because retrieval operations can ordinarily overlap with
+ * writing operations (i.e., put, remove, and their derivatives),
+ * retrievals can only be guaranteed to return the results of the most
+ * recently <em>completed</em> operations holding upon their
+ * onset. Retrieval operations may or may not return results
+ * reflecting in-progress writing operations.  However, the retrieval
+ * operations do always return consistent results -- either those
+ * holding before any single modification or after it, but never a
+ * nonsense result.  For aggregate operations such as putAll and
+ * clear, concurrent reads may reflect insertion or removal of only
+ * some entries. In those rare contexts in which you use a hash table
+ * to synchronize operations across threads (for example, to prevent
+ * reads until after clears), you should either encase operations
+ * in synchronized blocks, or instead use java.util.Hashtable.
+ *
+ * <p>
+ *
+ * This class also supports optional guaranteed
+ * exclusive reads, simply by surrounding a call within a synchronized
+ * block, as in <br> 
+ * <code>ConcurrentReaderHashMap t; ... Object v; <br>
+ * synchronized(t) { v = t.get(k); } </code> <br>
+ *
+ * But this is not usually necessary in practice. For
+ * example, it is generally inefficient to write:
+ *
+ * <pre>
+ *   ConcurrentReaderHashMap t; ...            // Inefficient version
+ *   Object key; ...
+ *   Object value; ...
+ *   synchronized(t) { 
+ *     if (!t.containsKey(key))
+ *       t.put(key, value);
+ *       // other code if not previously present
+ *     }
+ *     else {
+ *       // other code if it was previously present
+ *     }
+ *   }
+ *</pre>
+ * Instead, if the values are intended to be the same in each case, just take advantage of the fact that put returns
+ * null if the key was not previously present:
+ * <pre>
+ *   ConcurrentReaderHashMap t; ...                // Use this instead
+ *   Object key; ...
+ *   Object value; ...
+ *   Object oldValue = t.put(key, value);
+ *   if (oldValue == null) {
+ *     // other code if not previously present
+ *   }
+ *   else {
+ *     // other code if it was previously present
+ *   }
+ *</pre>
+ * <p>
+ *
+ * Iterators and Enumerations (i.e., those returned by
+ * keySet().iterator(), entrySet().iterator(), values().iterator(),
+ * keys(), and elements()) return elements reflecting the state of the
+ * hash table at some point at or since the creation of the
+ * iterator/enumeration.  They will return at most one instance of
+ * each element (via next()/nextElement()), but might or might not
+ * reflect puts and removes that have been processed since they were
+ * created.  They do <em>not</em> throw ConcurrentModificationException.
+ * However, these iterators are designed to be used by only one
+ * thread at a time. Sharing an iterator across multiple threads may
+ * lead to unpredictable results if the table is being concurrently
+ * modified.  Again, you can ensure interference-free iteration by
+ * enclosing the iteration in a synchronized block.  <p>
+ *
+ * This class may be used as a direct replacement for any use of
+ * java.util.Hashtable that does not depend on readers being blocked
+ * during updates. Like Hashtable but unlike java.util.HashMap,
+ * this class does NOT allow <tt>null</tt> to be used as a key or
+ * value.  This class is also typically faster than ConcurrentHashMap
+ * when there is usually only one thread updating the table, but 
+ * possibly many retrieving values from it.
+ * <p>
+ *
+ * Implementation note: A slightly faster implementation of
+ * this class will be possible once planned Java Memory Model
+ * revisions are in place.
+ *
+ * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
+ *
+ * @author Adapted from ConcurrentHashMap (Doug Lea)
+ * @author adapted by the Groovy community
+ */
+public class ConcurrentReaderHashMap 
+  extends AbstractMap 
+  implements Cloneable, Serializable {
+  private static final long serialVersionUID = -3225682440765612861L;
+
+
+  /*
+    The basic strategy is an optimistic-style scheme based on
+    the guarantee that the hash table and its lists are always
+    kept in a consistent enough state to be read without locking:
+
+    * Read operations first proceed without locking, by traversing the
+       apparently correct list of the apparently correct bin. If an
+       entry is found, but not invalidated (value field null), it is
+       returned. If not found, operations must recheck (after a memory
+       barrier) to make sure they are using both the right list and
+       the right table (which can change under re-sizes). If
+       invalidated, reads must acquire main update lock to wait out
+       the update, and then re-traverse.
+
+    * All list additions are at the front of each bin, making it easy
+       to check changes, and also fast to traverse.  Entry next
+       pointers are never assigned. Remove() builds new nodes when
+       necessary to preserve this.
+
+    * Remove() (also clear()) invalidates removed nodes to alert read
+       operations that they must wait out the full modifications.
+  */
+
+  /** A Serializable class for barrier lock **/
+  protected static class BarrierLock implements java.io.Serializable {
+      private static final long serialVersionUID = -2159505361622844863L;
+  }
+
+  /**
+   * Lock used only for its memory effects.
+   **/
+  protected final BarrierLock barrierLock = new BarrierLock();
+
+  /**
+   * field written to only to guarantee lock ordering.
+   **/
+  protected transient Object lastWrite;
+
+  /**
+   * Force a memory synchronization that will cause
+   * all readers to see table. Call only when already
+   * holding main sync lock.
+   **/
+  protected final void recordModification(Object x) { 
+    synchronized(barrierLock) {
+      lastWrite = x;
+    }
+  }
+
+  /**
+   * Get ref to table; the reference and the cells it
+   * accesses will be at least as fresh as from last
+   * use of barrierLock
+   **/
+  protected final Entry[] getTableForReading() { 
+    synchronized(barrierLock) {
+      return table; 
+    }
+  }
+
+
+  /**
+   * The default initial number of table slots for this table (32).
+   * Used when not otherwise specified in constructor.
+   **/
+  public static final int DEFAULT_INITIAL_CAPACITY = 32; 
+
+
+  /**
+   * The minimum capacity, used if a lower value is implicitly specified
+   * by either of the constructors with arguments.  
+   * MUST be a power of two.
+   */
+  private static final int MINIMUM_CAPACITY = 4;
+  
+  /**
+   * The maximum capacity, used if a higher value is implicitly specified
+   * by either of the constructors with arguments.
+   * MUST be a power of two &lt;= 1&lt;&lt;30.
+   */
+  private static final int MAXIMUM_CAPACITY = 1 << 30;
+  
+  /**
+   * The default load factor for this table (1.0).
+   * Used when not otherwise specified in constructor.
+   **/
+
+  public static final float DEFAULT_LOAD_FACTOR = 0.75f; 
+
+
+  /**
+   * The hash table data.
+   */
+  protected transient Entry[] table;
+
+  /**
+   * The total number of mappings in the hash table.
+   */
+  protected transient int count;
+
+  /**
+   * The table is rehashed when its size exceeds this threshold.  (The
+   * value of this field is always (int)(capacity * loadFactor).)
+   *
+   * @serial
+   */
+  protected int threshold;
+
+  /**
+   * The load factor for the hash table.
+   *
+   * @serial
+   */
+  protected float loadFactor;
+
+  /**
+   * Returns the appropriate capacity (power of two) for the specified 
+   * initial capacity argument.
+   */
+  private static int p2capacity(int initialCapacity) {
+    int cap = initialCapacity;
+    
+    // Compute the appropriate capacity
+    int result;
+    if (cap > MAXIMUM_CAPACITY || cap < 0) {
+      result = MAXIMUM_CAPACITY;
+    } else {
+      result = MINIMUM_CAPACITY;
+      while (result < cap)
+        result <<= 1;
+    }
+    return result;
+  }
+
+  /**
+   * Return hash code for Object x. Since we are using power-of-two
+   * tables, it is worth the effort to improve hashcode via
+   * the same multiplicative scheme as used in IdentityHashMap.
+   */
+  private static int hash(Object x) {
+    int h = x.hashCode();
+    // Multiply by 127 (quickly, via shifts), and mix in some high
+    // bits to help guard against bunching of codes that are
+    // consecutive or equally spaced.
+    return ((h << 7) - h + (h >>> 9) + (h >>> 17));
+  }
+
+  /** 
+   * Check for equality of non-null references x and y. 
+   **/
+  protected boolean eq(Object x, Object y) {
+    return x == y || x.equals(y);
+  }
+
+  /**
+   * Constructs a new, empty map with the specified initial 
+   * capacity and the specified load factor. 
+   *
+   * @param initialCapacity the initial capacity
+   *  The actual initial capacity is rounded to the nearest power of two.
+   * @param loadFactor  the load factor of the ConcurrentReaderHashMap
+   * @throws IllegalArgumentException  if the initial maximum number 
+   *               of elements is less
+   *               than zero, or if the load factor is non-positive.
+   */
+  public ConcurrentReaderHashMap(int initialCapacity, float loadFactor) {
+    if (loadFactor <= 0)
+      throw new IllegalArgumentException("Illegal Load factor: "+
+                                         loadFactor);
+    this.loadFactor = loadFactor;
+
+    int cap = p2capacity(initialCapacity);
+
+    table = new Entry[cap];
+    threshold = (int)(cap * loadFactor);
+  }
+
+  /**
+   * Constructs a new, empty map with the specified initial 
+   * capacity and default load factor.
+   *
+   * @param   initialCapacity   the initial capacity of the 
+   *                            ConcurrentReaderHashMap.
+   * @throws    IllegalArgumentException if the initial maximum number 
+   *              of elements is less than zero.
+   */
+  public ConcurrentReaderHashMap(int initialCapacity) {
+    this(initialCapacity, DEFAULT_LOAD_FACTOR);
+  }
+
+  /**
+   * Constructs a new, empty map with a default initial capacity
+   * and load factor.
+   */
+  public ConcurrentReaderHashMap() {
+    this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
+  }
+
+  /**
+   * Constructs a new map with the same mappings as the given map.  The
+   * map is created with a capacity of twice the number of mappings in
+   * the given map or 16 (whichever is greater), and a default load factor.
+   */
+  public ConcurrentReaderHashMap(Map t) {
+        this(Math.max((int) (t.size() / DEFAULT_LOAD_FACTOR) + 1, 16),
+             DEFAULT_LOAD_FACTOR);
+    putAll(t);
+  }
+
+  /**
+   * Returns the number of key-value mappings in this map.
+   *
+   * @return the number of key-value mappings in this map.
+   */
+  public synchronized int size() {
+    return count;
+  }
+
+  /**
+   * Returns <tt>true</tt> if this map contains no key-value mappings.
+   *
+   * @return <tt>true</tt> if this map contains no key-value mappings.
+   */
+  public synchronized boolean isEmpty() {
+    return count == 0;
+  }
+  
+
+
+  /**
+   * Returns the value to which the specified key is mapped in this table.
+   *
+   * @param   key   a key in the table.
+   * @return  the value to which the key is mapped in this table;
+   *          <code>null</code> if the key is not mapped to any value in
+   *          this table.
+   * @exception  NullPointerException  if the key is <code>null</code>.
+   * @see     #put(Object, Object)
+   */
+  public Object get(Object key) {
+
+    // throw null pointer exception if key null
+    int hash = hash(key);
+
+    /* 
+       Start off at the apparently correct bin.  If entry is found, we
+       need to check after a barrier anyway.  If not found, we need a
+       barrier to check if we are actually in right bin. So either
+       way, we encounter only one barrier unless we need to retry.
+       And we only need to fully synchronize if there have been
+       concurrent modifications.
+    */
+
+    Entry[] tab = table;
+    int index = hash & (tab.length - 1);
+    Entry first = tab[index];
+    Entry e = first;
+
+    for (;;) {
+      if (e == null) {
+
+        // If key apparently not there, check to
+        // make sure this was a valid read
+
+        Entry[] reread = getTableForReading();
+        if (tab == reread && first == tab[index])
+          return null;
+        else {
+          // Wrong list -- must restart traversal at new first
+          tab = reread;
+          e = first = tab[index = hash & (tab.length-1)];
+        }
+
+      }
+
+      else if (e.hash == hash && eq(key, e.key)) {
+        Object value = e.value;
+        if (value != null) 
+          return value;
+
+        // Entry was invalidated during deletion. But it could
+        // have been re-inserted, so we must re-traverse.
+        // To avoid useless contention, get lock to wait out modifications
+        // before re-traversing.
+
+        synchronized(this) {
+          tab = table;
+        }
+        e = first = tab[index = hash & (tab.length-1)];
+
+      }
+      else
+        e = e.next;
+    }
+  }
+
+
+  /**
+   * Tests if the specified object is a key in this table.
+   * 
+   * @param   key   possible key.
+   * @return  <code>true</code> if and only if the specified object 
+   *          is a key in this table, as determined by the 
+   *          <tt>equals</tt> method; <code>false</code> otherwise.
+   * @exception  NullPointerException  if the key is <code>null</code>.
+   * @see     #contains(Object)
+   */
+  public boolean containsKey(Object key) {
+    return get(key) != null;
+  }
+
+  /**
+   * Maps the specified <code>key</code> to the specified 
+   * <code>value</code> in this table. Neither the key nor the 
+   * value can be <code>null</code>. <p>
+   *
+   * The value can be retrieved by calling the <code>get</code> method 
+   * with a key that is equal to the original key. 
+   *
+   * @param      key     the table key.
+   * @param      value   the value.
+   * @return     the previous value of the specified key in this table,
+   *             or <code>null</code> if it did not have one.
+   * @exception  NullPointerException  if the key or value is <code>null</code>.
+   * @see     Object#equals(Object)
+   * @see     #get(Object)
+   */
+  public Object put(Object key, Object value) {
+    if (value == null) 
+      throw new NullPointerException();
+    
+    int hash = hash(key);
+    Entry[] tab = table;
+    int index = hash & (tab.length-1);
+    Entry first = tab[index];
+    Entry e;
+
+    for (e = first; e != null; e = e.next)
+      if (e.hash == hash && eq(key, e.key))
+        break;
+
+    synchronized(this) {
+      if (tab == table) {
+        if (e == null) {
+          //  make sure we are adding to correct list
+          if (first == tab[index]) {
+            //  Add to front of list
+            Entry newEntry = new Entry(hash, key, value, first);
+            tab[index] = newEntry;
+            if (++count >= threshold) rehash();
+            else recordModification(newEntry);
+            return null;
+          }
+        }
+        else {
+          Object oldValue = e.value; 
+          if (first == tab[index] && oldValue != null) {
+            e.value = value;
+            return oldValue;
+          }
+        }
+      }
+      
+      // retry if wrong list or lost race against concurrent remove
+      return sput(key, value, hash);
+    }
+  }
+
+
+  /**
+   * Continuation of put(), called only when sync lock is
+   * held and interference has been detected.
+   **/
+  protected Object sput(Object key, Object value, int hash) { 
+
+    Entry[] tab = table;
+    int index = hash & (tab.length-1);
+    Entry first = tab[index];
+    Entry e = first;
+
+    for (;;) {
+      if (e == null) {
+        Entry newEntry = new Entry(hash, key, value, first);
+        tab[index] = newEntry;
+        if (++count >= threshold) rehash();
+        else recordModification(newEntry);
+        return null;
+      }
+      else if (e.hash == hash && eq(key, e.key)) {
+        Object oldValue = e.value; 
+        e.value = value;
+        return oldValue;
+      }
+      else
+        e = e.next;
+    }
+  }
+
+
+  /**
+   * Rehashes the contents of this map into a new table
+   * with a larger capacity. This method is called automatically when the
+   * number of keys in this map exceeds its capacity and load factor.
+   */
+  protected void rehash() { 
+    Entry[] oldTable = table;
+    int oldCapacity = oldTable.length;
+    if (oldCapacity >= MAXIMUM_CAPACITY) {
+      threshold = Integer.MAX_VALUE; // avoid re-triggering
+      return;
+    }
+
+    int newCapacity = oldCapacity << 1;
+    int mask = newCapacity - 1;
+    threshold = (int)(newCapacity * loadFactor);
+
+    Entry[] newTable = new Entry[newCapacity];
+    /*
+     * Reclassify nodes in each list to new Map.  Because we are
+     * using power-of-two expansion, the elements from each bin
+     * must either stay at same index, or move to
+     * oldCapacity+index. We also eliminate unnecessary node
+     * creation by catching cases where old nodes can be reused
+     * because their next fields won't change. Statistically, at
+     * the default threshold, only about one-sixth of them need
+     * cloning. (The nodes they replace will be garbage
+     * collectible as soon as they are no longer referenced by any
+     * reader thread that may be in the midst of traversing table
+     * right now.)
+     */
+    
+    for (int i = 0; i < oldCapacity ; i++) {
+      // We need to guarantee that any existing reads of old Map can
+      // proceed. So we cannot yet null out each bin.
+      Entry e = oldTable[i];
+      
+      if (e != null) {
+        int idx = e.hash & mask;
+        Entry next = e.next;
+        
+        //  Single node on list
+        if (next == null) 
+          newTable[idx] = e;
+        
+        else {    
+          // Reuse trailing consecutive sequence of all same bit
+          Entry lastRun = e;
+          int lastIdx = idx;
+          for (Entry last = next; last != null; last = last.next) {
+            int k = last.hash & mask;
+            if (k != lastIdx) {
+              lastIdx = k;
+              lastRun = last;
+            }
+          }
+          newTable[lastIdx] = lastRun;
+          
+          // Clone all remaining nodes
+          for (Entry p = e; p != lastRun; p = p.next) {
+            int k = p.hash & mask;
+            newTable[k] = new Entry(p.hash, p.key, 
+                                    p.value, newTable[k]);
+          }
+        }
+      }
+    }
+
+    table = newTable;
+    recordModification(newTable);
+  }
+
+  /**
+   * Removes the key (and its corresponding value) from this 
+   * table. This method does nothing if the key is not in the table.
+   *
+   * @param   key   the key that needs to be removed.
+   * @return  the value to which the key had been mapped in this table,
+   *          or <code>null</code> if the key did not have a mapping.
+   * @exception  NullPointerException  if the key is
+   *               <code>null</code>.
+   */
+  public Object remove(Object key) {
+    /*
+      Find the entry, then 
+        1. Set value field to null, to force get() to retry
+        2. Rebuild the list without this entry.
+           All entries following removed node can stay in list, but
+           all preceding ones need to be cloned.  Traversals rely
+           on this strategy to ensure that elements will not be
+          repeated during iteration.
+    */
+          
+
+    int hash = hash(key);
+    Entry[] tab = table;
+    int index = hash & (tab.length-1);
+    Entry first = tab[index];
+    Entry e = first;
+      
+    for (e = first; e != null; e = e.next) 
+      if (e.hash == hash && eq(key, e.key)) 
+        break;
+
+
+    synchronized(this) {
+      if (tab == table) {
+        if (e == null) {
+          if (first == tab[index])
+            return null;
+        }
+        else {
+          Object oldValue = e.value;
+          if (first == tab[index] && oldValue != null) {
+            e.value = null;
+            count--;
+            
+            Entry head = e.next;
+            for (Entry p = first; p != e; p = p.next) 
+              head = new Entry(p.hash, p.key, p.value, head);
+            
+            tab[index] = head;
+            recordModification(head);
+            return oldValue;
+          }
+        }
+      }
+    
+      // Wrong list or interference
+      return sremove(key, hash);
+    }
+  }
+
+  /**
+   * Continuation of remove(), called only when sync lock is
+   * held and interference has been detected.
+   **/
+  protected Object sremove(Object key, int hash) {
+    Entry[] tab = table;
+    int index = hash & (tab.length-1);
+    Entry first = tab[index];
+      
+    for (Entry e = first; e != null; e = e.next) {
+      if (e.hash == hash && eq(key, e.key)) {
+        Object oldValue = e.value;
+        e.value = null;
+        count--;
+        Entry head = e.next;
+        for (Entry p = first; p != e; p = p.next) 
+          head = new Entry(p.hash, p.key, p.value, head);
+        
+        tab[index] = head;
+        recordModification(head);
+        return oldValue;
+      }
+    }
+    return null;
+  }
+
+
+  /**
+   * Returns <tt>true</tt> if this map maps one or more keys to the
+   * specified value. Note: This method requires a full internal
+   * traversal of the hash table, and so is much slower than
+   * method <tt>containsKey</tt>.
+   *
+   * @param value value whose presence in this map is to be tested.
+   * @return <tt>true</tt> if this map maps one or more keys to the
+   * specified value.  
+   * @exception  NullPointerException  if the value is <code>null</code>.
+   */
+  public boolean containsValue(Object value) {
+    if (value == null) throw new NullPointerException();
+
+    Entry tab[] = getTableForReading();
+    
+    for (int i = 0 ; i < tab.length; ++i) {
+      for (Entry e = tab[i] ; e != null ; e = e.next) 
+        if (value.equals(e.value))
+          return true;
+    }
+
+    return false;
+  }
+
+  /**
+   * Tests if some key maps into the specified value in this table.
+   * This operation is more expensive than the <code>containsKey</code>
+   * method.<p>
+   *
+   * Note that this method is identical in functionality to containsValue,
+   * (which is part of the Map interface in the collections framework).
+   * 
+   * @param      value   a value to search for.
+   * @return     <code>true</code> if and only if some key maps to the
+   *             <code>value</code> argument in this table as 
+   *             determined by the <tt>equals</tt> method;
+   *             <code>false</code> otherwise.
+   * @exception  NullPointerException  if the value is <code>null</code>.
+   * @see        #containsKey(Object)
+   * @see        #containsValue(Object)
+   * @see      Map
+   */
+  public boolean contains(Object value) {
+    return containsValue(value);
+  }
+
+
+  /**
+   * Copies all of the mappings from the specified map to this one.
+   * 
+   * These mappings replace any mappings that this map had for any of the
+   * keys currently in the specified Map.
+   *
+   * @param t Mappings to be stored in this map.
+   */
+  public synchronized void putAll(Map t) {
+    int n = t.size();
+    if (n == 0)
+      return;
+
+    // Expand enough to hold at least n elements without resizing.
+    // We can only resize table by factor of two at a time.
+    // It is faster to rehash with fewer elements, so do it now.
+    while (n >= threshold)
+      rehash();
+
+    for (Iterator it = t.entrySet().iterator(); it.hasNext();) {
+      Map.Entry entry = (Map.Entry) it.next();
+      Object key = entry.getKey();
+      Object value = entry.getValue();
+      put(key, value);
+    }
+  }
+
+
+  /**
+   * Removes all mappings from this map.
+   */
+  public synchronized void clear() {
+    Entry tab[] = table;
+    for (int i = 0; i < tab.length ; ++i) { 
+
+      // must invalidate all to force concurrent get's to wait and then retry
+      for (Entry e = tab[i]; e != null; e = e.next) 
+        e.value = null; 
+
+      tab[i] = null;
+    }
+    count = 0;
+    recordModification(tab);
+  }
+
+  /**
+   * Returns a shallow copy of this 
+   * <tt>ConcurrentReaderHashMap</tt> instance: the keys and
+   * values themselves are not cloned.
+   *
+   * @return a shallow copy of this map.
+   */
+  public synchronized Object clone() {
+    try { 
+      ConcurrentReaderHashMap t = (ConcurrentReaderHashMap)super.clone();
+
+      t.keySet = null;
+      t.entrySet = null;
+      t.values = null;
+
+      Entry[] tab = table;
+      t.table = new Entry[tab.length];
+      Entry[] ttab = t.table;
+
+      for (int i = 0; i < tab.length; ++i) {
+        Entry first = null;
+        for (Entry e = tab[i]; e != null; e = e.next) 
+          first = new Entry(e.hash, e.key, e.value, first);
+        ttab[i] = first;
+      }
+
+      return t;
+    } 
+    catch (CloneNotSupportedException e) { 
+      // this shouldn't happen, since we are Cloneable
+      throw new InternalError();
+    }
+  }
+
+  // Views
+
+  protected transient Set keySet = null;
+  protected transient Set entrySet = null;
+  protected transient Collection values = null;
+
+  /**
+   * Returns a set view of the keys contained in this map.  The set is
+   * backed by the map, so changes to the map are reflected in the set, and
+   * vice-versa.  The set supports element removal, which removes the
+   * corresponding mapping from this map, via the <tt>Iterator.remove</tt>,
+   * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt>, and
+   * <tt>clear</tt> operations.  It does not support the <tt>add</tt> or
+   * <tt>addAll</tt> operations.
+   *
+   * @return a set view of the keys contained in this map.
+   */
+  public Set keySet() {
+    Set ks = keySet;
+    return (ks != null)? ks : (keySet = new KeySet());
+  }
+  
+  private class KeySet extends AbstractSet {
+    public Iterator iterator() {
+      return new KeyIterator();
+    }
+    public int size() {
+      return ConcurrentReaderHashMap.this.size();
+    }
+    public boolean contains(Object o) {
+      return ConcurrentReaderHashMap.this.containsKey(o);
+    }
+    public boolean remove(Object o) {
+      return ConcurrentReaderHashMap.this.remove(o) != null;
+    }
+    public void clear() {
+      ConcurrentReaderHashMap.this.clear();
+    }
+    public Object[] toArray() {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray();
+    }
+    public Object[] toArray(Object[] a) {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray(a);
+    }
+  }
+
+  /**
+   * Returns a collection view of the values contained in this map.  The
+   * collection is backed by the map, so changes to the map are reflected in
+   * the collection, and vice-versa.  The collection supports element
+   * removal, which removes the corresponding mapping from this map, via the
+   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
+   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
+   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
+   *
+   * @return a collection view of the values contained in this map.
+   */
+  public Collection values() {
+    Collection vs = values;
+    return (vs != null)? vs : (values = new Values());
+  }
+  
+  private class Values extends AbstractCollection {
+    public Iterator iterator() {
+      return new ValueIterator();
+    }
+    public int size() {
+      return ConcurrentReaderHashMap.this.size();
+    }
+    public boolean contains(Object o) {
+      return ConcurrentReaderHashMap.this.containsValue(o);
+    }
+    public void clear() {
+      ConcurrentReaderHashMap.this.clear();
+    }
+    public Object[] toArray() {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray();
+    }
+    public Object[] toArray(Object[] a) {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray(a);
+    }
+  }
+
+  /**
+   * Returns a collection view of the mappings contained in this map.  Each
+   * element in the returned collection is a <tt>Map.Entry</tt>.  The
+   * collection is backed by the map, so changes to the map are reflected in
+   * the collection, and vice-versa.  The collection supports element
+   * removal, which removes the corresponding mapping from the map, via the
+   * <tt>Iterator.remove</tt>, <tt>Collection.remove</tt>,
+   * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> operations.
+   * It does not support the <tt>add</tt> or <tt>addAll</tt> operations.
+   *
+   * @return a collection view of the mappings contained in this map.
+   */
+  public Set entrySet() {
+    Set es = entrySet;
+    return (es != null) ? es : (entrySet = new EntrySet());
+  }
+
+  private class EntrySet extends AbstractSet {
+    public Iterator iterator() {
+      return new HashIterator();
+    }
+    public boolean contains(Object o) {
+      if (!(o instanceof Map.Entry))
+        return false;
+      Map.Entry entry = (Map.Entry)o;
+      Object v = ConcurrentReaderHashMap.this.get(entry.getKey());
+      return v != null && v.equals(entry.getValue());
+    }
+    public boolean remove(Object o) {
+      if (!(o instanceof Map.Entry))
+        return false;
+      return ConcurrentReaderHashMap.this.findAndRemoveEntry((Map.Entry)o);
+    }
+    public int size() {
+      return ConcurrentReaderHashMap.this.size();
+    }
+    public void clear() {
+      ConcurrentReaderHashMap.this.clear();
+    }
+    public Object[] toArray() {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray();
+    }
+    public Object[] toArray(Object[] a) {
+      Collection c = new ArrayList();
+      for (Iterator i = iterator(); i.hasNext(); )
+          c.add(i.next());
+      return c.toArray(a);
+    }
+  }
+
+  /**
+   * Helper method for entrySet.remove
+   **/
+  protected synchronized boolean findAndRemoveEntry(Map.Entry entry) {
+    Object key = entry.getKey();
+    Object v = get(key);
+    if (v != null && v.equals(entry.getValue())) {
+      remove(key);
+      return true;
+    }
+    else
+      return false;
+  }
+
+  /**
+   * Returns an enumeration of the keys in this table.
+   *
+   * @return  an enumeration of the keys in this table.
+   * @see     Enumeration
+   * @see     #elements()
+   * @see   #keySet()
+   * @see   Map
+   */
+  public Enumeration keys() {
+    return new KeyIterator();
+  }
+
+  /**
+   * Returns an enumeration of the values in this table.
+   * Use the Enumeration methods on the returned object to fetch the elements
+   * sequentially.
+   *
+   * @return  an enumeration of the values in this table.
+   * @see     java.util.Enumeration
+   * @see     #keys()
+   * @see   #values()
+   * @see   Map
+   */
+  public Enumeration elements() {
+    return new ValueIterator();
+  }
+
+
+  /**
+   * ConcurrentReaderHashMap collision list entry.
+   */
+  protected static class Entry implements Map.Entry {
+
+    /* 
+       The use of volatile for value field ensures that
+       we can detect status changes without synchronization.
+       The other fields are never changed, and are
+       marked as final. 
+    */
+    protected final int hash;
+    protected final Object key;
+    protected final Entry next;
+    protected volatile Object value;
+
+    Entry(int hash, Object key, Object value, Entry next) {
+      this.hash = hash;
+      this.key = key;
+      this.next = next;
+      this.value = value;
+    }
+
+    // Map.Entry Ops 
+
+    public Object getKey() {
+      return key;
+    }
+
+    /**
+     * Get the value.  Note: In an entrySet or entrySet.iterator,
+     * unless the set or iterator is used under synchronization of the
+     * table as a whole (or you can otherwise guarantee lack of
+     * concurrent modification), <tt>getValue</tt> <em>might</em>
+     * return null, reflecting the fact that the entry has been
+     * concurrently removed. However, there are no assurances that
+     * concurrent removals will be reflected using this method.
+     * 
+     * @return     the current value, or null if the entry has been 
+     * detectably removed.
+     **/
+    public Object getValue() {
+      return value; 
+    }
+
+    /**
+     * Set the value of this entry.  Note: In an entrySet or
+     * entrySet.iterator), unless the set or iterator is used under
+     * synchronization of the table as a whole (or you can otherwise
+     * guarantee lack of concurrent modification), <tt>setValue</tt>
+     * is not strictly guaranteed to actually replace the value field
+     * obtained via the <tt>get</tt> operation of the underlying hash
+     * table in multi-threaded applications.  If iterator-wide
+     * synchronization is not used, and any other concurrent
+     * <tt>put</tt> or <tt>remove</tt> operations occur, sometimes
+     * even to <em>other</em> entries, then this change is not
+     * guaranteed to be reflected in the hash table. (It might, or it
+     * might not. There are no assurances either way.)
+     *
+     * @param      value   the new value.
+     * @return     the previous value, or null if entry has been detectably
+     * removed.
+     * @exception  NullPointerException  if the value is <code>null</code>.
+     * 
+     **/
+    public Object setValue(Object value) {
+      if (value == null)
+        throw new NullPointerException();
+      Object oldValue = this.value;
+      this.value = value;
+      return oldValue;
+    }
+
+    public boolean equals(Object o) {
+      if (!(o instanceof Map.Entry))
+        return false;
+      Map.Entry e = (Map.Entry)o;
+      return (key.equals(e.getKey()) && value.equals(e.getValue()));
+    }
+    
+    public int hashCode() {
+      return  key.hashCode() ^ value.hashCode();
+    }
+    
+    public String toString() {
+      return key + "=" + value;
+    }
+
+  }
+
+  protected class HashIterator implements Iterator, Enumeration {
+    protected final Entry[] tab;           // snapshot of table
+    protected int index;                   // current slot 
+    protected Entry entry = null;          // current node of slot
+    protected Object currentKey;           // key for current node
+    protected Object currentValue;         // value for current node
+    protected Entry lastReturned = null;   // last node returned by next
+
+    protected HashIterator() {
+      tab = ConcurrentReaderHashMap.this.getTableForReading();
+      index = tab.length - 1;
+    }
+
+    public boolean hasMoreElements() { return hasNext(); }
+    public Object nextElement() { return next(); }
+
+
+    public boolean hasNext() {
+
+      /*
+        currentKey and currentValue are set here to ensure that next()
+        returns normally if hasNext() returns true. This avoids
+        surprises especially when final element is removed during
+        traversal -- instead, we just ignore the removal during
+        current traversal.  
+      */
+
+      for (;;) {
+        if (entry != null) {
+          Object v = entry.value;
+          if (v != null) {
+            currentKey = entry.key;
+            currentValue = v;
+            return true;
+          }
+          else
+            entry = entry.next;
+        }
+
+        while (entry == null && index >= 0)
+          entry = tab[index--];
+
+        if (entry == null) {
+          currentKey = currentValue = null;
+          return false;
+        }
+      }
+    }
+
+    protected Object returnValueOfNext() { return entry; }
+
+    public Object next() {
+      if (currentKey == null && !hasNext())
+        throw new NoSuchElementException();
+
+      Object result = returnValueOfNext();
+      lastReturned = entry;
+      currentKey = currentValue = null;
+      entry = entry.next;
+      return result;
+    }
+
+    public void remove() {
+      if (lastReturned == null)
+        throw new IllegalStateException();
+      ConcurrentReaderHashMap.this.remove(lastReturned.key);
+      lastReturned = null;
+    }
+
+  }
+
+
+  protected class KeyIterator extends HashIterator {
+    protected Object returnValueOfNext() { return currentKey; }
+  }
+  
+  protected class ValueIterator extends HashIterator {
+    protected Object returnValueOfNext() { return currentValue; }
+  }
+  
+
+
+  /**
+   * Save the state of the <tt>ConcurrentReaderHashMap</tt> 
+   * instance to a stream (i.e.,
+   * serialize it).
+   *
+   * @param s the stream
+   * @serialData The <i>capacity</i> of the
+   * ConcurrentReaderHashMap (the length of the
+   * bucket array) is emitted (int), followed  by the
+   * <i>size</i> of the ConcurrentReaderHashMap (the number of key-value
+   * mappings), followed by the key (Object) and value (Object)
+   * for each key-value mapping represented by the ConcurrentReaderHashMap
+   * The key-value mappings are emitted in no particular order.
+   */
+  private synchronized void writeObject(java.io.ObjectOutputStream s)
+    throws IOException  {
+    // Write out the threshold, loadfactor, and any hidden stuff
+    s.defaultWriteObject();
+    
+    // Write out number of buckets
+    s.writeInt(table.length);
+    
+    // Write out size (number of Mappings)
+    s.writeInt(count);
+    
+    // Write out keys and values (alternating)
+    for (int index = table.length-1; index >= 0; index--) {
+      Entry entry = table[index];
+      
+      while (entry != null) {
+        s.writeObject(entry.key);
+        s.writeObject(entry.value);
+        entry = entry.next;
+      }
+    }
+  }
+
+  /**
+   * Reconstitute the <tt>ConcurrentReaderHashMap</tt> 
+   * instance from a stream (i.e.,
+   * deserialize it).
+   *
+   * @param s the stream
+   */
+  private synchronized void readObject(java.io.ObjectInputStream s)
+    throws IOException, ClassNotFoundException  {
+    // Read in the threshold, loadfactor, and any hidden stuff
+    s.defaultReadObject();
+
+    // Read in number of buckets and allocate the bucket array;
+    int numBuckets = s.readInt();
+    table = new Entry[numBuckets];
+    
+    // Read in size (number of Mappings)
+    int size = s.readInt();
+    
+    // Read the keys and values, and put the mappings in the table
+    for (int i=0; i<size; i++) {
+      Object key = s.readObject();
+      Object value = s.readObject();
+      put(key, value);
+    }
+  }
+  
+  /** 
+   * @return the number of slots in this table
+   **/
+  public synchronized int capacity() {
+    return table.length;
+  }
+
+  /** 
+   * @return the load factor
+   **/
+  public float loadFactor() {
+    return loadFactor;
+  }
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/metaclass/MethodSelectionException.java b/src/main/java/org/codehaus/groovy/runtime/metaclass/MethodSelectionException.java
index 06272ed..027e7ff 100644
--- a/src/main/java/org/codehaus/groovy/runtime/metaclass/MethodSelectionException.java
+++ b/src/main/java/org/codehaus/groovy/runtime/metaclass/MethodSelectionException.java
@@ -1,102 +1,102 @@
-/*
- *  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.runtime.metaclass;
-
-import groovy.lang.GroovyRuntimeException;
-import groovy.lang.MetaMethod;
-import org.codehaus.groovy.reflection.CachedConstructor;
-import org.codehaus.groovy.util.FastArray;
-
-import java.lang.reflect.Modifier;
-
-/**
- * This exception is thrown if the runtime is unable to select
- * a method. This class builds the exception text when calling 
- * getMessage.
- * <p>
- * <b>Note:</b> This exception as for internal use only!
- * 
- * @since Groovy 1.1
- */
-public class MethodSelectionException extends GroovyRuntimeException {
-
-    private static final long serialVersionUID = 8126246630023758333L;
-    private final String methodName;
-    private final FastArray methods;
-    private final Class[] arguments;
-    
-    /**
-     * Creates a new MethodSelectionException.
-     * @param methodName name of the method
-     * @param methods    a FastArray of methods
-     * @param arguments  the method call argument classes
-     */
-    public MethodSelectionException(String methodName, FastArray methods, Class[] arguments) {
-        super(methodName);
-        this.methodName = methodName;
-        this.arguments = arguments;
-        this.methods = methods;
-    }
-
-    public String getMessage() {
-        StringBuilder buffer = new StringBuilder();
-        buffer.append("Could not find which method ").append(methodName);
-        appendClassNames(buffer,arguments);
-        buffer.append(" to invoke from this list:");
-        appendMethods(buffer);
-        return buffer.toString();
-    }
-    
-    
-    private static void appendClassNames(StringBuilder argBuf, Class[] classes) {
-        argBuf.append("(");
-        for (int i = 0; i < classes.length; i++) {
-            if (i > 0) {
-                argBuf.append(", ");
-            }
-            Class clazz = classes[i];
-            String name = clazz==null? "null": clazz.getName();
-            argBuf.append(name);
-        }
-        argBuf.append(")");
-    }
-    
-    private void appendMethods(StringBuilder buffer) {
-        for (int i = 0; i < methods.size; i++) {
-            buffer.append("\n  ");
-            Object methodOrConstructor = methods.get(i);
-            if (methodOrConstructor instanceof MetaMethod) {
-                MetaMethod method = (MetaMethod) methodOrConstructor;
-                buffer.append(Modifier.toString(method.getModifiers()));
-                buffer.append(" ").append(method.getReturnType().getName());
-                buffer.append(" ").append(method.getDeclaringClass().getName());
-                buffer.append("#");
-                buffer.append(method.getName());
-                appendClassNames(buffer,method.getNativeParameterTypes());
-            }
-            else {
-                CachedConstructor method = (CachedConstructor) methodOrConstructor;
-                buffer.append(Modifier.toString(method.cachedConstructor.getModifiers()));
-                buffer.append(" ").append(method.cachedConstructor.getDeclaringClass().getName());
-                buffer.append("#<init>");
-                appendClassNames(buffer,method.getNativeParameterTypes());
-            }
-        }
-    }
+/*
+ *  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.runtime.metaclass;
+
+import groovy.lang.GroovyRuntimeException;
+import groovy.lang.MetaMethod;
+import org.codehaus.groovy.reflection.CachedConstructor;
+import org.codehaus.groovy.util.FastArray;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * This exception is thrown if the runtime is unable to select
+ * a method. This class builds the exception text when calling 
+ * getMessage.
+ * <p>
+ * <b>Note:</b> This exception as for internal use only!
+ * 
+ * @since Groovy 1.1
+ */
+public class MethodSelectionException extends GroovyRuntimeException {
+
+    private static final long serialVersionUID = 8126246630023758333L;
+    private final String methodName;
+    private final FastArray methods;
+    private final Class[] arguments;
+    
+    /**
+     * Creates a new MethodSelectionException.
+     * @param methodName name of the method
+     * @param methods    a FastArray of methods
+     * @param arguments  the method call argument classes
+     */
+    public MethodSelectionException(String methodName, FastArray methods, Class[] arguments) {
+        super(methodName);
+        this.methodName = methodName;
+        this.arguments = arguments;
+        this.methods = methods;
+    }
+
+    public String getMessage() {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append("Could not find which method ").append(methodName);
+        appendClassNames(buffer,arguments);
+        buffer.append(" to invoke from this list:");
+        appendMethods(buffer);
+        return buffer.toString();
+    }
+    
+    
+    private static void appendClassNames(StringBuilder argBuf, Class[] classes) {
+        argBuf.append("(");
+        for (int i = 0; i < classes.length; i++) {
+            if (i > 0) {
+                argBuf.append(", ");
+            }
+            Class clazz = classes[i];
+            String name = clazz==null? "null": clazz.getName();
+            argBuf.append(name);
+        }
+        argBuf.append(")");
+    }
+    
+    private void appendMethods(StringBuilder buffer) {
+        for (int i = 0; i < methods.size; i++) {
+            buffer.append("\n  ");
+            Object methodOrConstructor = methods.get(i);
+            if (methodOrConstructor instanceof MetaMethod) {
+                MetaMethod method = (MetaMethod) methodOrConstructor;
+                buffer.append(Modifier.toString(method.getModifiers()));
+                buffer.append(" ").append(method.getReturnType().getName());
+                buffer.append(" ").append(method.getDeclaringClass().getName());
+                buffer.append("#");
+                buffer.append(method.getName());
+                appendClassNames(buffer,method.getNativeParameterTypes());
+            }
+            else {
+                CachedConstructor method = (CachedConstructor) methodOrConstructor;
+                buffer.append(Modifier.toString(method.cachedConstructor.getModifiers()));
+                buffer.append(" ").append(method.cachedConstructor.getDeclaringClass().getName());
+                buffer.append("#<init>");
+                appendClassNames(buffer,method.getNativeParameterTypes());
+            }
+        }
+    }
 }
\ No newline at end of file
diff --git a/src/main/java/org/codehaus/groovy/runtime/typehandling/GroovyCastException.java b/src/main/java/org/codehaus/groovy/runtime/typehandling/GroovyCastException.java
index f9cace8..053353a 100644
--- a/src/main/java/org/codehaus/groovy/runtime/typehandling/GroovyCastException.java
+++ b/src/main/java/org/codehaus/groovy/runtime/typehandling/GroovyCastException.java
@@ -1,87 +1,87 @@
-/*
- *  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.runtime.typehandling;
-
-public class GroovyCastException extends ClassCastException {
-
-    private static final long serialVersionUID = 6859089155641797356L;
-
-    /**
-     * @param objectToCast object we tried to cast
-     * @param classToCastTo class we tried to cast to
-     * @param cause not kept but we pass on message from this Exception if any
-     */
-    public GroovyCastException(Object objectToCast, Class classToCastTo, Exception cause) {
-        super(makeMessage(objectToCast,classToCastTo) + " due to: " +
-                cause.getClass().getName() + (cause.getMessage() == null ? "" : ": " + cause.getMessage()));
-    }
-
-    /**
-     * @param objectToCast object we tried to cast
-     * @param classToCastTo class we tried to cast to
-     */
-    public GroovyCastException(Object objectToCast, Class classToCastTo) {
-        super(makeMessage(objectToCast,classToCastTo));
-    }
-
-    /**
-     * @param message custom Exception message
-     */
-    public GroovyCastException(String message) {
-        super(message);
-    }
-
-    private static String makeMessage(Object objectToCast, Class classToCastTo) {
-       String classToCastFrom;
-       Object msgObject = objectToCast;
-       if (objectToCast!=null) {
-           classToCastFrom = objectToCast.getClass().getName();
-       } else {
-           msgObject = "null";
-           classToCastFrom = "null";
-       }
-       String msg = 
-               "Cannot cast object '" + msgObject + "' " +
-               "with class '" + classToCastFrom + "' " +
-               "to class '" + classToCastTo.getName() + "'";
-
-       if (objectToCast==null){
-           msg += getWrapper(classToCastTo);
-       }
-
-       return msg;
-    }
-
-    private static String getWrapper(Class cls) {
-        Class ncls = cls;
-        if (cls==byte.class)        {ncls=Byte.class;}
-        else if (cls==short.class)  {ncls=Short.class;}
-        else if (cls==char.class)   {ncls=Character.class;}
-        else if (cls==int.class)    {ncls=Integer.class;}
-        else if (cls==long.class)   {ncls=Long.class;}
-        else if (cls==float.class)  {ncls=Float.class;}
-        else if (cls==double.class) {ncls=Double.class;}
-        if (cls!=null && ncls!=cls) {
-            String msg = ". Try '" + ncls.getName() + "' instead";
-            return msg;
-        }
-        return "";
-    }
-
-}
+/*
+ *  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.runtime.typehandling;
+
+public class GroovyCastException extends ClassCastException {
+
+    private static final long serialVersionUID = 6859089155641797356L;
+
+    /**
+     * @param objectToCast object we tried to cast
+     * @param classToCastTo class we tried to cast to
+     * @param cause not kept but we pass on message from this Exception if any
+     */
+    public GroovyCastException(Object objectToCast, Class classToCastTo, Exception cause) {
+        super(makeMessage(objectToCast,classToCastTo) + " due to: " +
+                cause.getClass().getName() + (cause.getMessage() == null ? "" : ": " + cause.getMessage()));
+    }
+
+    /**
+     * @param objectToCast object we tried to cast
+     * @param classToCastTo class we tried to cast to
+     */
+    public GroovyCastException(Object objectToCast, Class classToCastTo) {
+        super(makeMessage(objectToCast,classToCastTo));
+    }
+
+    /**
+     * @param message custom Exception message
+     */
+    public GroovyCastException(String message) {
+        super(message);
+    }
+
+    private static String makeMessage(Object objectToCast, Class classToCastTo) {
+       String classToCastFrom;
+       Object msgObject = objectToCast;
+       if (objectToCast!=null) {
+           classToCastFrom = objectToCast.getClass().getName();
+       } else {
+           msgObject = "null";
+           classToCastFrom = "null";
+       }
+       String msg = 
+               "Cannot cast object '" + msgObject + "' " +
+               "with class '" + classToCastFrom + "' " +
+               "to class '" + classToCastTo.getName() + "'";
+
+       if (objectToCast==null){
+           msg += getWrapper(classToCastTo);
+       }
+
+       return msg;
+    }
+
+    private static String getWrapper(Class cls) {
+        Class ncls = cls;
+        if (cls==byte.class)        {ncls=Byte.class;}
+        else if (cls==short.class)  {ncls=Short.class;}
+        else if (cls==char.class)   {ncls=Character.class;}
+        else if (cls==int.class)    {ncls=Integer.class;}
+        else if (cls==long.class)   {ncls=Long.class;}
+        else if (cls==float.class)  {ncls=Float.class;}
+        else if (cls==double.class) {ncls=Double.class;}
+        if (cls!=null && ncls!=cls) {
+            String msg = ". Try '" + ncls.getName() + "' instead";
+            return msg;
+        }
+        return "";
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/runtime/typehandling/package.html b/src/main/java/org/codehaus/groovy/runtime/typehandling/package.html
index fab5318..a5f4506 100644
--- a/src/main/java/org/codehaus/groovy/runtime/typehandling/package.html
+++ b/src/main/java/org/codehaus/groovy/runtime/typehandling/package.html
@@ -1,30 +1,30 @@
-<!--
-
-     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 org.codehaus.groovy.runtime.typehandling*</title>
-  </head>
-  <body>
-    <p>Classes used to execute special actions based on the type. 
-    This includes mathematical operations and wrapper classes.
-    </p>
-  </body>
-</html>
+<!--
+
+     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 org.codehaus.groovy.runtime.typehandling*</title>
+  </head>
+  <body>
+    <p>Classes used to execute special actions based on the type. 
+    This includes mathematical operations and wrapper classes.
+    </p>
+  </body>
+</html>
diff --git a/src/main/java/org/codehaus/groovy/tools/StringHelper.java b/src/main/java/org/codehaus/groovy/tools/StringHelper.java
index 53b3b9e..c01388a 100644
--- a/src/main/java/org/codehaus/groovy/tools/StringHelper.java
+++ b/src/main/java/org/codehaus/groovy/tools/StringHelper.java
@@ -1,86 +1,86 @@
-/*
- *  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.tools;
-
-import java.util.LinkedList;
-import java.util.List;
-
-public class StringHelper {
-    private static final char
-        SPACE = ' ', SINGLE_QUOTE = '\'', DOUBLE_QUOTE = '"';
-    private static final String[] EMPTY_STRING_ARRAY = new String[0];
-
-    /**
-     * This method tokenizes a string by space characters, 
-     * but ignores spaces in quoted parts,that are parts in 
-     * '' or "". The method does allows the usage of "" in '' 
-     * and '' in "". The space character between tokens is not 
-     * returned. 
-     * 
-     * @param s the string to tokenize
-     * @return the tokens
-     */
-    public static String[] tokenizeUnquoted(String s) {
-        List tokens = new LinkedList();
-        int first = 0;
-        while (first < s.length()) {
-            first = skipWhitespace(s, first);
-            int last = scanToken(s, first);
-            if (first < last) {
-                tokens.add(s.substring(first, last));
-            }
-            first = last;
-        }
-        return (String[])tokens.toArray(EMPTY_STRING_ARRAY);
-    }
-
-    private static int scanToken(String s, int pos0) {
-        int pos = pos0;
-        while (pos < s.length()) {
-            char c = s.charAt(pos);
-            if (SPACE==c) break;
-            pos++;
-            if (SINGLE_QUOTE == c) {
-                pos = scanQuoted(s, pos, SINGLE_QUOTE);
-            } else if (DOUBLE_QUOTE == c) {
-                pos = scanQuoted(s, pos, DOUBLE_QUOTE);
-            }
-        }
-        return pos;
-    }
-
-    private static int scanQuoted(String s, int pos0, char quote) {
-        int pos = pos0;
-        while (pos < s.length()) {
-            char c = s.charAt(pos++);
-            if (quote == c) break;
-        }
-        return pos;
-    }
-
-    private static int skipWhitespace(String s, int pos0) {
-        int pos = pos0;
-        while (pos < s.length()) {
-            char c = s.charAt(pos);
-            if (SPACE!=c) break;
-            pos++;
-        }
-        return pos;
-    } 
-}
+/*
+ *  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.tools;
+
+import java.util.LinkedList;
+import java.util.List;
+
+public class StringHelper {
+    private static final char
+        SPACE = ' ', SINGLE_QUOTE = '\'', DOUBLE_QUOTE = '"';
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+    /**
+     * This method tokenizes a string by space characters, 
+     * but ignores spaces in quoted parts,that are parts in 
+     * '' or "". The method does allows the usage of "" in '' 
+     * and '' in "". The space character between tokens is not 
+     * returned. 
+     * 
+     * @param s the string to tokenize
+     * @return the tokens
+     */
+    public static String[] tokenizeUnquoted(String s) {
+        List tokens = new LinkedList();
+        int first = 0;
+        while (first < s.length()) {
+            first = skipWhitespace(s, first);
+            int last = scanToken(s, first);
+            if (first < last) {
+                tokens.add(s.substring(first, last));
+            }
+            first = last;
+        }
+        return (String[])tokens.toArray(EMPTY_STRING_ARRAY);
+    }
+
+    private static int scanToken(String s, int pos0) {
+        int pos = pos0;
+        while (pos < s.length()) {
+            char c = s.charAt(pos);
+            if (SPACE==c) break;
+            pos++;
+            if (SINGLE_QUOTE == c) {
+                pos = scanQuoted(s, pos, SINGLE_QUOTE);
+            } else if (DOUBLE_QUOTE == c) {
+                pos = scanQuoted(s, pos, DOUBLE_QUOTE);
+            }
+        }
+        return pos;
+    }
+
+    private static int scanQuoted(String s, int pos0, char quote) {
+        int pos = pos0;
+        while (pos < s.length()) {
+            char c = s.charAt(pos++);
+            if (quote == c) break;
+        }
+        return pos;
+    }
+
+    private static int skipWhitespace(String s, int pos0) {
+        int pos = pos0;
+        while (pos < s.length()) {
+            char c = s.charAt(pos);
+            if (SPACE!=c) break;
+            pos++;
+        }
+        return pos;
+    } 
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformUtil.java b/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformUtil.java
index de50cb5..35bf848 100644
--- a/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformUtil.java
+++ b/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformUtil.java
@@ -1,184 +1,184 @@
-/*
- *  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;
-
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.BooleanExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.IfStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.objectweb.asm.Opcodes;
-
-import java.util.List;
-
-/**
- * @deprecated use org.codehaus.groovy.ast.tools.GeneralUtils
- */
-@Deprecated
-public abstract class AbstractASTTransformUtil implements Opcodes {
-    @Deprecated
-    public static Statement assignStatement(Expression target, Expression value) {
-        return GeneralUtils.assignS(target, value);
-    }
-
-    @Deprecated
-    public static Statement createConstructorStatementDefault(FieldNode fNode) {
-        return GeneralUtils.createConstructorStatementDefault(fNode);
-    }
-
-    @Deprecated
-    public static ExpressionStatement declStatement(Expression result, Expression init) {
-        return (ExpressionStatement) GeneralUtils.declS(result, init);
-    }
-
-    @Deprecated
-    public static BooleanExpression differentExpr(Expression self, Expression other) {
-        return GeneralUtils.notX(GeneralUtils.sameX(self, other));
-    }
-
-    @Deprecated
-    public static BooleanExpression differentFieldExpr(FieldNode fNode, Expression other) {
-        return GeneralUtils.notX(GeneralUtils.hasSameFieldX(fNode, other));
-    }
-
-    @Deprecated
-    public static BooleanExpression differentPropertyExpr(PropertyNode pNode, Expression other) {
-        return GeneralUtils.notX(GeneralUtils.hasSamePropertyX(pNode, other));
-    }
-
-    @Deprecated
-    public static BooleanExpression equalsNullExpr(Expression argExpr) {
-        return GeneralUtils.equalsNullX(argExpr);
-    }
-
-    @Deprecated
-    public static Expression findArg(String argName) {
-        return GeneralUtils.findArg(argName);
-    }
-
-    @Deprecated
-    public static List<FieldNode> getInstanceNonPropertyFields(ClassNode cNode) {
-        return GeneralUtils.getInstanceNonPropertyFields(cNode);
-    }
-
-    @Deprecated
-    public static List<PropertyNode> getInstanceProperties(ClassNode cNode) {
-        return GeneralUtils.getInstanceProperties(cNode);
-    }
-
-    @Deprecated
-    public static List<FieldNode> getInstancePropertyFields(ClassNode cNode) {
-        return GeneralUtils.getInstancePropertyFields(cNode);
-    }
-
-    @Deprecated
-    public static List<FieldNode> getSuperNonPropertyFields(ClassNode cNode) {
-        return GeneralUtils.getSuperNonPropertyFields(cNode);
-    }
-
-    @Deprecated
-    public static List<FieldNode> getSuperPropertyFields(ClassNode cNode) {
-        return GeneralUtils.getSuperPropertyFields(cNode);
-    }
-
-    @Deprecated
-    public static boolean hasDeclaredMethod(ClassNode cNode, String name, int argsCount) {
-        return GeneralUtils.hasDeclaredMethod(cNode, name, argsCount);
-    }
-
-    @Deprecated
-    public static BooleanExpression identicalExpr(Expression self, Expression other) {
-        return GeneralUtils.sameX(self, other);
-    }
-
-    @Deprecated
-    public static BooleanExpression isInstanceOf(Expression objectExpression, ClassNode cNode) {
-        return GeneralUtils.isInstanceOfX(objectExpression, cNode);
-    }
-
-    @Deprecated
-    public static BooleanExpression isInstanceof(ClassNode cNode, Expression other) {
-        return GeneralUtils.isInstanceOfX(other, cNode);
-    }
-
-    @Deprecated
-    public static BooleanExpression isOneExpr(Expression expr) {
-        return GeneralUtils.isOneX(expr);
-    }
-
-    @Deprecated
-    public static boolean isOrImplements(ClassNode fieldType, ClassNode interfaceType) {
-        return GeneralUtils.isOrImplements(fieldType, interfaceType);
-    }
-
-    @Deprecated
-    public static BooleanExpression isTrueExpr(Expression argExpr) {
-        return GeneralUtils.isTrueX(argExpr);
-    }
-
-    @Deprecated
-    public static BooleanExpression isZeroExpr(Expression expr) {
-        return GeneralUtils.isZeroX(expr);
-    }
-
-    @Deprecated
-    public static BooleanExpression notNullExpr(Expression argExpr) {
-        return GeneralUtils.notNullX(argExpr);
-    }
-
-    @Deprecated
-    public static Statement returnFalseIfFieldNotEqual(FieldNode fNode, Expression other) {
-        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasEqualFieldX(fNode, other)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
-    }
-
-    @Deprecated
-    public static Statement returnFalseIfNotInstanceof(ClassNode cNode, Expression other) {
-        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.isInstanceOfX(other, cNode)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
-    }
-
-    @Deprecated
-    public static IfStatement returnFalseIfNull(Expression other) {
-        return (IfStatement) GeneralUtils.ifS(GeneralUtils.equalsNullX(other), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
-    }
-
-    @Deprecated
-    public static Statement returnFalseIfPropertyNotEqual(PropertyNode pNode, Expression other) {
-        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasEqualPropertyX(pNode, other)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
-    }
-
-    @Deprecated
-    public static Statement returnFalseIfWrongType(ClassNode cNode, Expression other) {
-        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasClassX(other, cNode)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
-    }
-
-    @Deprecated
-    public static IfStatement returnTrueIfIdentical(Expression self, Expression other) {
-        return (IfStatement) GeneralUtils.ifS(GeneralUtils.sameX(self, other), GeneralUtils.returnS(GeneralUtils.constX(Boolean.TRUE)));
-    }
-
-    @Deprecated
-    public static Statement safeExpression(Expression fieldExpr, Expression expression) {
-        return GeneralUtils.safeExpression(fieldExpr, expression);
-    }
-
-}
+/*
+ *  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;
+
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.expr.BooleanExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.ast.stmt.IfStatement;
+import org.codehaus.groovy.ast.stmt.Statement;
+import org.codehaus.groovy.ast.tools.GeneralUtils;
+import org.objectweb.asm.Opcodes;
+
+import java.util.List;
+
+/**
+ * @deprecated use org.codehaus.groovy.ast.tools.GeneralUtils
+ */
+@Deprecated
+public abstract class AbstractASTTransformUtil implements Opcodes {
+    @Deprecated
+    public static Statement assignStatement(Expression target, Expression value) {
+        return GeneralUtils.assignS(target, value);
+    }
+
+    @Deprecated
+    public static Statement createConstructorStatementDefault(FieldNode fNode) {
+        return GeneralUtils.createConstructorStatementDefault(fNode);
+    }
+
+    @Deprecated
+    public static ExpressionStatement declStatement(Expression result, Expression init) {
+        return (ExpressionStatement) GeneralUtils.declS(result, init);
+    }
+
+    @Deprecated
+    public static BooleanExpression differentExpr(Expression self, Expression other) {
+        return GeneralUtils.notX(GeneralUtils.sameX(self, other));
+    }
+
+    @Deprecated
+    public static BooleanExpression differentFieldExpr(FieldNode fNode, Expression other) {
+        return GeneralUtils.notX(GeneralUtils.hasSameFieldX(fNode, other));
+    }
+
+    @Deprecated
+    public static BooleanExpression differentPropertyExpr(PropertyNode pNode, Expression other) {
+        return GeneralUtils.notX(GeneralUtils.hasSamePropertyX(pNode, other));
+    }
+
+    @Deprecated
+    public static BooleanExpression equalsNullExpr(Expression argExpr) {
+        return GeneralUtils.equalsNullX(argExpr);
+    }
+
+    @Deprecated
+    public static Expression findArg(String argName) {
+        return GeneralUtils.findArg(argName);
+    }
+
+    @Deprecated
+    public static List<FieldNode> getInstanceNonPropertyFields(ClassNode cNode) {
+        return GeneralUtils.getInstanceNonPropertyFields(cNode);
+    }
+
+    @Deprecated
+    public static List<PropertyNode> getInstanceProperties(ClassNode cNode) {
+        return GeneralUtils.getInstanceProperties(cNode);
+    }
+
+    @Deprecated
+    public static List<FieldNode> getInstancePropertyFields(ClassNode cNode) {
+        return GeneralUtils.getInstancePropertyFields(cNode);
+    }
+
+    @Deprecated
+    public static List<FieldNode> getSuperNonPropertyFields(ClassNode cNode) {
+        return GeneralUtils.getSuperNonPropertyFields(cNode);
+    }
+
+    @Deprecated
+    public static List<FieldNode> getSuperPropertyFields(ClassNode cNode) {
+        return GeneralUtils.getSuperPropertyFields(cNode);
+    }
+
+    @Deprecated
+    public static boolean hasDeclaredMethod(ClassNode cNode, String name, int argsCount) {
+        return GeneralUtils.hasDeclaredMethod(cNode, name, argsCount);
+    }
+
+    @Deprecated
+    public static BooleanExpression identicalExpr(Expression self, Expression other) {
+        return GeneralUtils.sameX(self, other);
+    }
+
+    @Deprecated
+    public static BooleanExpression isInstanceOf(Expression objectExpression, ClassNode cNode) {
+        return GeneralUtils.isInstanceOfX(objectExpression, cNode);
+    }
+
+    @Deprecated
+    public static BooleanExpression isInstanceof(ClassNode cNode, Expression other) {
+        return GeneralUtils.isInstanceOfX(other, cNode);
+    }
+
+    @Deprecated
+    public static BooleanExpression isOneExpr(Expression expr) {
+        return GeneralUtils.isOneX(expr);
+    }
+
+    @Deprecated
+    public static boolean isOrImplements(ClassNode fieldType, ClassNode interfaceType) {
+        return GeneralUtils.isOrImplements(fieldType, interfaceType);
+    }
+
+    @Deprecated
+    public static BooleanExpression isTrueExpr(Expression argExpr) {
+        return GeneralUtils.isTrueX(argExpr);
+    }
+
+    @Deprecated
+    public static BooleanExpression isZeroExpr(Expression expr) {
+        return GeneralUtils.isZeroX(expr);
+    }
+
+    @Deprecated
+    public static BooleanExpression notNullExpr(Expression argExpr) {
+        return GeneralUtils.notNullX(argExpr);
+    }
+
+    @Deprecated
+    public static Statement returnFalseIfFieldNotEqual(FieldNode fNode, Expression other) {
+        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasEqualFieldX(fNode, other)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
+    }
+
+    @Deprecated
+    public static Statement returnFalseIfNotInstanceof(ClassNode cNode, Expression other) {
+        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.isInstanceOfX(other, cNode)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
+    }
+
+    @Deprecated
+    public static IfStatement returnFalseIfNull(Expression other) {
+        return (IfStatement) GeneralUtils.ifS(GeneralUtils.equalsNullX(other), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
+    }
+
+    @Deprecated
+    public static Statement returnFalseIfPropertyNotEqual(PropertyNode pNode, Expression other) {
+        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasEqualPropertyX(pNode, other)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
+    }
+
+    @Deprecated
+    public static Statement returnFalseIfWrongType(ClassNode cNode, Expression other) {
+        return GeneralUtils.ifS(GeneralUtils.notX(GeneralUtils.hasClassX(other, cNode)), GeneralUtils.returnS(GeneralUtils.constX(Boolean.FALSE)));
+    }
+
+    @Deprecated
+    public static IfStatement returnTrueIfIdentical(Expression self, Expression other) {
+        return (IfStatement) GeneralUtils.ifS(GeneralUtils.sameX(self, other), GeneralUtils.returnS(GeneralUtils.constX(Boolean.TRUE)));
+    }
+
+    @Deprecated
+    public static Statement safeExpression(Expression fieldExpr, Expression expression) {
+        return GeneralUtils.safeExpression(fieldExpr, expression);
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformation.java
index c13c8ef..4fc13d2 100644
--- a/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/AbstractASTTransformation.java
@@ -1,494 +1,494 @@
-/*
- *  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;
-
-import org.apache.groovy.ast.tools.AnnotatedNodeUtils;
-import org.apache.groovy.ast.tools.MethodNodeUtils;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.ClassExpression;
-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.VariableExpression;
-import org.codehaus.groovy.ast.tools.BeanUtils;
-import org.codehaus.groovy.ast.tools.GeneralUtils;
-import org.codehaus.groovy.ast.tools.GenericsUtils;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
-import org.codehaus.groovy.runtime.StringGroovyMethods;
-import org.codehaus.groovy.syntax.SyntaxException;
-import org.objectweb.asm.Opcodes;
-
-import java.lang.annotation.Retention;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-
-import static groovy.transform.Undefined.isUndefined;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstanceNonPropertyFieldNames;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getSuperNonPropertyFields;
-
-public abstract class AbstractASTTransformation implements Opcodes, ASTTransformation, ErrorCollecting {
-    public static final ClassNode RETENTION_CLASSNODE = ClassHelper.makeWithoutCaching(Retention.class);
-
-    protected SourceUnit sourceUnit;
-
-    /**
-     * Copies all <tt>candidateAnnotations</tt> with retention policy {@link java.lang.annotation.RetentionPolicy#RUNTIME}
-     * and {@link java.lang.annotation.RetentionPolicy#CLASS}.
-     * <p>
-     * Annotations with {@link org.codehaus.groovy.runtime.GeneratedClosure} members are not supported for now.
-     */
-    protected List<AnnotationNode> copyAnnotatedNodeAnnotations(final AnnotatedNode annotatedNode, String myTypeName) {
-        final List<AnnotationNode> copiedAnnotations = new ArrayList<AnnotationNode>();
-        final List<AnnotationNode> notCopied = new ArrayList<AnnotationNode>();
-        GeneralUtils.copyAnnotatedNodeAnnotations(annotatedNode, copiedAnnotations, notCopied);
-        for (AnnotationNode annotation : notCopied) {
-            addError(myTypeName + " does not support keeping Closure annotation members.", annotation);
-        }
-        return copiedAnnotations;
-    }
-
-    /**
-     * If the transform is associated with a single annotation, returns a name suitable for displaying in error messages.
-     *
-     * @return The simple name of the annotation including the "@" or null if no such name is defined
-     */
-    public String getAnnotationName() {
-        return null;
-    }
-
-    protected void init(ASTNode[] nodes, SourceUnit sourceUnit) {
-        if (nodes == null || nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
-            throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + (nodes == null ? null : Arrays.asList(nodes)));
-        }
-        this.sourceUnit = sourceUnit;
-    }
-
-    public boolean memberHasValue(AnnotationNode node, String name, Object value) {
-        final Expression member = node.getMember(name);
-        return member instanceof ConstantExpression && ((ConstantExpression) member).getValue().equals(value);
-    }
-
-    public Object getMemberValue(AnnotationNode node, String name) {
-        final Expression member = node.getMember(name);
-        if (member instanceof ConstantExpression) return ((ConstantExpression) member).getValue();
-        return null;
-    }
-
-    public static String getMemberStringValue(AnnotationNode node, String name, String defaultValue) {
-        final Expression member = node.getMember(name);
-        if (member instanceof ConstantExpression) {
-            Object result = ((ConstantExpression) member).getValue();
-            if (result instanceof String && isUndefined((String) result)) result = null;
-            if (result != null) return result.toString();
-        }
-        return defaultValue;
-    }
-
-    public static String getMemberStringValue(AnnotationNode node, String name) {
-        return getMemberStringValue(node, name, null);
-    }
-
-    public int getMemberIntValue(AnnotationNode node, String name) {
-        Object value = getMemberValue(node, name);
-        if (value instanceof Integer) {
-            return (Integer) value;
-        }
-        return 0;
-    }
-
-    public ClassNode getMemberClassValue(AnnotationNode node, String name) {
-        return getMemberClassValue(node, name, null);
-    }
-
-    public ClassNode getMemberClassValue(AnnotationNode node, String name, ClassNode defaultValue) {
-        final Expression member = node.getMember(name);
-        if (member != null) {
-            if (member instanceof ClassExpression) {
-                if (!isUndefined(member.getType())) return member.getType();
-            } else if (member instanceof VariableExpression) {
-                addError("Error expecting to find class value for '" + name + "' but found variable: " + member.getText() + ". Missing import?", node);
-                return null;
-            } else if (member instanceof ConstantExpression) {
-                addError("Error expecting to find class value for '" + name + "' but found constant: " + member.getText() + "!", node);
-                return null;
-            }
-        }
-        return defaultValue;
-    }
-
-    public static List<String> getMemberStringList(AnnotationNode anno, String name) {
-        Expression expr = anno.getMember(name);
-        if (expr == null) {
-            return null;
-        }
-        if (expr instanceof ListExpression) {
-            final ListExpression listExpression = (ListExpression) expr;
-            if (isUndefinedMarkerList(listExpression)) {
-                return null;
-            }
-
-            return getValueStringList(listExpression);
-        }
-        return tokenize(getMemberStringValue(anno, name));
-    }
-
-    private static boolean isUndefinedMarkerList(ListExpression listExpression) {
-        if (listExpression.getExpressions().size() != 1) return false;
-        Expression itemExpr = listExpression.getExpression(0);
-        if (itemExpr == null) return false;
-        if (itemExpr instanceof ConstantExpression) {
-            Object value = ((ConstantExpression) itemExpr).getValue();
-            if (value instanceof String && isUndefined((String)value)) return true;
-        } else if (itemExpr instanceof ClassExpression && isUndefined(itemExpr.getType())) {
-            return true;
-        }
-        return false;
-    }
-
-    @Deprecated
-    public static List<String> getMemberList(AnnotationNode anno, String name) {
-        List<String> list;
-        Expression expr = anno.getMember(name);
-        if (expr instanceof ListExpression) {
-            final ListExpression listExpression = (ListExpression) expr;
-            list = getValueStringList(listExpression);
-        } else {
-            list = tokenize(getMemberStringValue(anno, name));
-        }
-        return list;
-    }
-
-    private static List<String> getValueStringList(ListExpression listExpression) {
-        List<String> list = new ArrayList<String>();
-        for (Expression itemExpr : listExpression.getExpressions()) {
-            if (itemExpr instanceof ConstantExpression) {
-                Object value = ((ConstantExpression) itemExpr).getValue();
-                if (value != null) list.add(value.toString());
-            }
-        }
-        return list;
-    }
-
-    @Deprecated
-    public List<ClassNode> getClassList(AnnotationNode anno, String name) {
-        List<ClassNode> list = new ArrayList<ClassNode>();
-        Expression expr = anno.getMember(name);
-        if (expr instanceof ListExpression) {
-            final ListExpression listExpression = (ListExpression) expr;
-            list = getTypeList(listExpression);
-        } else if (expr instanceof ClassExpression) {
-            ClassNode cn = expr.getType();
-            if (cn != null) list.add(cn);
-        }
-        return list;
-    }
-
-    public List<ClassNode> getMemberClassList(AnnotationNode anno, String name) {
-        List<ClassNode> list = new ArrayList<ClassNode>();
-        Expression expr = anno.getMember(name);
-        if (expr == null) {
-            return null;
-        }
-        if (expr instanceof ListExpression) {
-            final ListExpression listExpression = (ListExpression) expr;
-            if (isUndefinedMarkerList(listExpression)) {
-                return null;
-            }
-            list = getTypeList(listExpression);
-        } else if (expr instanceof ClassExpression) {
-            ClassNode cn = expr.getType();
-            if (isUndefined(cn)) return null;
-            if (cn != null) list.add(cn);
-        }
-        return list;
-    }
-
-    private static List<ClassNode> getTypeList(ListExpression listExpression) {
-        List<ClassNode> list = new ArrayList<ClassNode>();
-        for (Expression itemExpr : listExpression.getExpressions()) {
-            if (itemExpr instanceof ClassExpression) {
-                ClassNode cn = itemExpr.getType();
-                if (cn != null) list.add(cn);
-            }
-        }
-        return list;
-    }
-
-    public void addError(String msg, ASTNode expr) {
-        sourceUnit.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(
-                        new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(),
-                                expr.getLastLineNumber(), expr.getLastColumnNumber()),
-                        sourceUnit)
-        );
-    }
-
-    protected boolean checkNotInterface(ClassNode cNode, String annotationName) {
-        if (cNode.isInterface()) {
-            addError("Error processing interface '" + cNode.getName() + "'. " +
-                    annotationName + " not allowed for interfaces.", cNode);
-            return false;
-        }
-        return true;
-    }
-
-    public boolean hasAnnotation(ClassNode node, ClassNode annotation) {
-        return AnnotatedNodeUtils.hasAnnotation(node, annotation);
-    }
-
-    public static List<String> tokenize(String rawExcludes) {
-        return rawExcludes == null ? new ArrayList<String>() : StringGroovyMethods.tokenize(rawExcludes, ", ");
-    }
-
-    public static boolean deemedInternalName(String name) {
-        return name.contains("$");
-    }
-
-    public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes) {
-        return shouldSkipUndefinedAware(name, excludes, includes, false);
-    }
-
-    public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes, boolean allNames) {
-        return (excludes != null && excludes.contains(name)) ||
-            (!allNames && deemedInternalName(name)) ||
-            (includes != null && !includes.contains(name));
-    }
-
-    public static boolean shouldSkip(String name, List<String> excludes, List<String> includes) {
-        return shouldSkip(name, excludes, includes, false);
-    }
-
-    public static boolean shouldSkip(String name, List<String> excludes, List<String> includes, boolean allNames) {
-        return (excludes != null && excludes.contains(name)) ||
-            (!allNames && deemedInternalName(name)) ||
-            (includes != null && !includes.isEmpty() && !includes.contains(name));
-    }
-
-    @Deprecated
-    public static boolean shouldSkipOnDescriptor(boolean checkReturn, Map genericsSpec, MethodNode mNode, List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
-        String descriptor = mNode.getTypeDescriptor();
-        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
-        for (ClassNode cn : excludeTypes) {
-            List<ClassNode> remaining = new LinkedList<ClassNode>();
-            remaining.add(cn);
-            Map updatedGenericsSpec = new HashMap(genericsSpec);
-            while (!remaining.isEmpty()) {
-                ClassNode next = remaining.remove(0);
-                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
-                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
-                    for (MethodNode mn : next.getMethods()) {
-                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
-                        if (checkReturn) {
-                            String md = correctedMethodNode.getTypeDescriptor();
-                            if (md.equals(descriptor)) return true;
-                        } else {
-                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
-                            if (md.equals(descriptorNoReturn)) return true;
-                        }
-                    }
-                    remaining.addAll(Arrays.asList(next.getInterfaces()));
-                }
-            }
-        }
-        if (includeTypes.isEmpty()) return false;
-        for (ClassNode cn : includeTypes) {
-            List<ClassNode> remaining = new LinkedList<ClassNode>();
-            remaining.add(cn);
-            Map updatedGenericsSpec = new HashMap(genericsSpec);
-            while (!remaining.isEmpty()) {
-                ClassNode next = remaining.remove(0);
-                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
-                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
-                    for (MethodNode mn : next.getMethods()) {
-                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
-                        if (checkReturn) {
-                            String md = correctedMethodNode.getTypeDescriptor();
-                            if (md.equals(descriptor)) return false;
-                        } else {
-                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
-                            if (md.equals(descriptorNoReturn)) return false;
-                        }
-                    }
-                    remaining.addAll(Arrays.asList(next.getInterfaces()));
-                }
-            }
-        }
-        return true;
-    }
-    public static boolean shouldSkipOnDescriptorUndefinedAware(boolean checkReturn, Map genericsSpec, MethodNode mNode,
-                                                  List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
-        String descriptor = mNode.getTypeDescriptor();
-        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
-        if (excludeTypes != null) {
-            for (ClassNode cn : excludeTypes) {
-                List<ClassNode> remaining = new LinkedList<ClassNode>();
-                remaining.add(cn);
-                Map updatedGenericsSpec = new HashMap(genericsSpec);
-                while (!remaining.isEmpty()) {
-                    ClassNode next = remaining.remove(0);
-                    if (!next.equals(ClassHelper.OBJECT_TYPE)) {
-                        updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
-                        for (MethodNode mn : next.getMethods()) {
-                            MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
-                            if (checkReturn) {
-                                String md = correctedMethodNode.getTypeDescriptor();
-                                if (md.equals(descriptor)) return true;
-                            } else {
-                                String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
-                                if (md.equals(descriptorNoReturn)) return true;
-                            }
-                        }
-                        remaining.addAll(Arrays.asList(next.getInterfaces()));
-                    }
-                }
-            }
-        }
-        if (includeTypes == null) return false;
-        for (ClassNode cn : includeTypes) {
-            List<ClassNode> remaining = new LinkedList<ClassNode>();
-            remaining.add(cn);
-            Map updatedGenericsSpec = new HashMap(genericsSpec);
-            while (!remaining.isEmpty()) {
-                ClassNode next = remaining.remove(0);
-                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
-                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
-                    for (MethodNode mn : next.getMethods()) {
-                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
-                        if (checkReturn) {
-                            String md = correctedMethodNode.getTypeDescriptor();
-                            if (md.equals(descriptor)) return false;
-                        } else {
-                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
-                            if (md.equals(descriptorNoReturn)) return false;
-                        }
-                    }
-                    remaining.addAll(Arrays.asList(next.getInterfaces()));
-                }
-            }
-        }
-        return true;
-    }
-
-    @Deprecated
-    protected boolean checkIncludeExclude(AnnotationNode node, List<String> excludes, List<String> includes, String typeName) {
-        if (includes != null && !includes.isEmpty() && excludes != null && !excludes.isEmpty()) {
-            addError("Error during " + typeName + " processing: Only one of 'includes' and 'excludes' should be supplied not both.", node);
-            return false;
-        }
-        return true;
-    }
-
-    protected boolean checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes, String typeName) {
-        if (includes != null && excludes != null && !excludes.isEmpty()) {
-            addError("Error during " + typeName + " processing: Only one of 'includes' and 'excludes' should be supplied not both.", node);
-            return false;
-        }
-        return true;
-    }
-
-    @Deprecated
-    protected void checkIncludeExclude(AnnotationNode node, List<String> excludes, List<String> includes, List<ClassNode> excludeTypes, List<ClassNode> includeTypes, String typeName) {
-        int found = 0;
-        if (includes != null && !includes.isEmpty()) found++;
-        if (excludes != null && !excludes.isEmpty()) found++;
-        if (includeTypes != null && !includeTypes.isEmpty()) found++;
-        if (excludeTypes != null && !excludeTypes.isEmpty()) found++;
-        if (found > 1) {
-            addError("Error during " + typeName + " processing: Only one of 'includes', 'excludes', 'includeTypes' and 'excludeTypes' should be supplied.", node);
-        }
-    }
-
-    protected void checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes,
-                                        List<ClassNode> excludeTypes, List<ClassNode> includeTypes, String typeName) {
-        int found = 0;
-        if (includes != null) found++;
-        if (excludes != null && !excludes.isEmpty()) found++;
-        if (includeTypes != null) found++;
-        if (excludeTypes != null && !excludeTypes.isEmpty()) found++;
-        if (found > 1) {
-            addError("Error during " + typeName + " processing: Only one of 'includes', 'excludes', 'includeTypes' and 'excludeTypes' should be supplied.", node);
-        }
-    }
-
-    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields) {
-        return checkPropertyList(cNode, propertyNameList, listName, anno, typeName, includeFields, false, false);
-    }
-
-    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties) {
-        return checkPropertyList(cNode, propertyNameList, listName, anno, typeName, includeFields, includeSuperProperties, allProperties, false, false);
-    }
-
-    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties, boolean includeSuperFields, boolean includeStatic) {
-        if (propertyNameList == null || propertyNameList.isEmpty()) {
-            return true;
-        }
-        final List<String> pNames = new ArrayList<String>();
-        for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, includeSuperProperties, includeStatic, allProperties)) {
-            pNames.add(pNode.getField().getName());
-        }
-        boolean result = true;
-        if (includeFields || includeSuperFields) {
-            final List<String> fNames = new ArrayList<String>();
-            if (includeFields) {
-                fNames.addAll(getInstanceNonPropertyFieldNames(cNode));
-            }
-            if (includeSuperFields) {
-                List<FieldNode> superNonPropertyFields = getSuperNonPropertyFields(cNode.getSuperClass());
-                for (FieldNode fn : superNonPropertyFields) {
-                    fNames.add(fn.getName());
-                }
-            }
-            for (String pName : propertyNameList) {
-                if (!pNames.contains(pName) && !fNames.contains(pName)) {
-                    addError("Error during " + typeName + " processing: '" + listName + "' property or field '" + pName + "' does not exist.", anno);
-                    result = false;
-                }
-            }
-        } else {
-            for (String pName : propertyNameList) {
-                if (!pNames.contains(pName)) {
-                    addError("Error during " + typeName + " processing: '" + listName + "' property '" + pName + "' does not exist.", anno);
-                    result = false;
-                }
-            }
-        }
-        return result;
-    }
-
-    /**
-     * @deprecated use GenericsUtils#nonGeneric
-     */
-    @Deprecated
-    public static ClassNode nonGeneric(ClassNode type) {
-        return GenericsUtils.nonGeneric(type);
-    }
-
-}
+/*
+ *  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;
+
+import org.apache.groovy.ast.tools.AnnotatedNodeUtils;
+import org.apache.groovy.ast.tools.MethodNodeUtils;
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.PropertyNode;
+import org.codehaus.groovy.ast.expr.ClassExpression;
+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.VariableExpression;
+import org.codehaus.groovy.ast.tools.BeanUtils;
+import org.codehaus.groovy.ast.tools.GeneralUtils;
+import org.codehaus.groovy.ast.tools.GenericsUtils;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.control.messages.SyntaxErrorMessage;
+import org.codehaus.groovy.runtime.StringGroovyMethods;
+import org.codehaus.groovy.syntax.SyntaxException;
+import org.objectweb.asm.Opcodes;
+
+import java.lang.annotation.Retention;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+import static groovy.transform.Undefined.isUndefined;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getInstanceNonPropertyFieldNames;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.getSuperNonPropertyFields;
+
+public abstract class AbstractASTTransformation implements Opcodes, ASTTransformation, ErrorCollecting {
+    public static final ClassNode RETENTION_CLASSNODE = ClassHelper.makeWithoutCaching(Retention.class);
+
+    protected SourceUnit sourceUnit;
+
+    /**
+     * Copies all <tt>candidateAnnotations</tt> with retention policy {@link java.lang.annotation.RetentionPolicy#RUNTIME}
+     * and {@link java.lang.annotation.RetentionPolicy#CLASS}.
+     * <p>
+     * Annotations with {@link org.codehaus.groovy.runtime.GeneratedClosure} members are not supported for now.
+     */
+    protected List<AnnotationNode> copyAnnotatedNodeAnnotations(final AnnotatedNode annotatedNode, String myTypeName) {
+        final List<AnnotationNode> copiedAnnotations = new ArrayList<AnnotationNode>();
+        final List<AnnotationNode> notCopied = new ArrayList<AnnotationNode>();
+        GeneralUtils.copyAnnotatedNodeAnnotations(annotatedNode, copiedAnnotations, notCopied);
+        for (AnnotationNode annotation : notCopied) {
+            addError(myTypeName + " does not support keeping Closure annotation members.", annotation);
+        }
+        return copiedAnnotations;
+    }
+
+    /**
+     * If the transform is associated with a single annotation, returns a name suitable for displaying in error messages.
+     *
+     * @return The simple name of the annotation including the "@" or null if no such name is defined
+     */
+    public String getAnnotationName() {
+        return null;
+    }
+
+    protected void init(ASTNode[] nodes, SourceUnit sourceUnit) {
+        if (nodes == null || nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
+            throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + (nodes == null ? null : Arrays.asList(nodes)));
+        }
+        this.sourceUnit = sourceUnit;
+    }
+
+    public boolean memberHasValue(AnnotationNode node, String name, Object value) {
+        final Expression member = node.getMember(name);
+        return member instanceof ConstantExpression && ((ConstantExpression) member).getValue().equals(value);
+    }
+
+    public Object getMemberValue(AnnotationNode node, String name) {
+        final Expression member = node.getMember(name);
+        if (member instanceof ConstantExpression) return ((ConstantExpression) member).getValue();
+        return null;
+    }
+
+    public static String getMemberStringValue(AnnotationNode node, String name, String defaultValue) {
+        final Expression member = node.getMember(name);
+        if (member instanceof ConstantExpression) {
+            Object result = ((ConstantExpression) member).getValue();
+            if (result instanceof String && isUndefined((String) result)) result = null;
+            if (result != null) return result.toString();
+        }
+        return defaultValue;
+    }
+
+    public static String getMemberStringValue(AnnotationNode node, String name) {
+        return getMemberStringValue(node, name, null);
+    }
+
+    public int getMemberIntValue(AnnotationNode node, String name) {
+        Object value = getMemberValue(node, name);
+        if (value instanceof Integer) {
+            return (Integer) value;
+        }
+        return 0;
+    }
+
+    public ClassNode getMemberClassValue(AnnotationNode node, String name) {
+        return getMemberClassValue(node, name, null);
+    }
+
+    public ClassNode getMemberClassValue(AnnotationNode node, String name, ClassNode defaultValue) {
+        final Expression member = node.getMember(name);
+        if (member != null) {
+            if (member instanceof ClassExpression) {
+                if (!isUndefined(member.getType())) return member.getType();
+            } else if (member instanceof VariableExpression) {
+                addError("Error expecting to find class value for '" + name + "' but found variable: " + member.getText() + ". Missing import?", node);
+                return null;
+            } else if (member instanceof ConstantExpression) {
+                addError("Error expecting to find class value for '" + name + "' but found constant: " + member.getText() + "!", node);
+                return null;
+            }
+        }
+        return defaultValue;
+    }
+
+    public static List<String> getMemberStringList(AnnotationNode anno, String name) {
+        Expression expr = anno.getMember(name);
+        if (expr == null) {
+            return null;
+        }
+        if (expr instanceof ListExpression) {
+            final ListExpression listExpression = (ListExpression) expr;
+            if (isUndefinedMarkerList(listExpression)) {
+                return null;
+            }
+
+            return getValueStringList(listExpression);
+        }
+        return tokenize(getMemberStringValue(anno, name));
+    }
+
+    private static boolean isUndefinedMarkerList(ListExpression listExpression) {
+        if (listExpression.getExpressions().size() != 1) return false;
+        Expression itemExpr = listExpression.getExpression(0);
+        if (itemExpr == null) return false;
+        if (itemExpr instanceof ConstantExpression) {
+            Object value = ((ConstantExpression) itemExpr).getValue();
+            if (value instanceof String && isUndefined((String)value)) return true;
+        } else if (itemExpr instanceof ClassExpression && isUndefined(itemExpr.getType())) {
+            return true;
+        }
+        return false;
+    }
+
+    @Deprecated
+    public static List<String> getMemberList(AnnotationNode anno, String name) {
+        List<String> list;
+        Expression expr = anno.getMember(name);
+        if (expr instanceof ListExpression) {
+            final ListExpression listExpression = (ListExpression) expr;
+            list = getValueStringList(listExpression);
+        } else {
+            list = tokenize(getMemberStringValue(anno, name));
+        }
+        return list;
+    }
+
+    private static List<String> getValueStringList(ListExpression listExpression) {
+        List<String> list = new ArrayList<String>();
+        for (Expression itemExpr : listExpression.getExpressions()) {
+            if (itemExpr instanceof ConstantExpression) {
+                Object value = ((ConstantExpression) itemExpr).getValue();
+                if (value != null) list.add(value.toString());
+            }
+        }
+        return list;
+    }
+
+    @Deprecated
+    public List<ClassNode> getClassList(AnnotationNode anno, String name) {
+        List<ClassNode> list = new ArrayList<ClassNode>();
+        Expression expr = anno.getMember(name);
+        if (expr instanceof ListExpression) {
+            final ListExpression listExpression = (ListExpression) expr;
+            list = getTypeList(listExpression);
+        } else if (expr instanceof ClassExpression) {
+            ClassNode cn = expr.getType();
+            if (cn != null) list.add(cn);
+        }
+        return list;
+    }
+
+    public List<ClassNode> getMemberClassList(AnnotationNode anno, String name) {
+        List<ClassNode> list = new ArrayList<ClassNode>();
+        Expression expr = anno.getMember(name);
+        if (expr == null) {
+            return null;
+        }
+        if (expr instanceof ListExpression) {
+            final ListExpression listExpression = (ListExpression) expr;
+            if (isUndefinedMarkerList(listExpression)) {
+                return null;
+            }
+            list = getTypeList(listExpression);
+        } else if (expr instanceof ClassExpression) {
+            ClassNode cn = expr.getType();
+            if (isUndefined(cn)) return null;
+            if (cn != null) list.add(cn);
+        }
+        return list;
+    }
+
+    private static List<ClassNode> getTypeList(ListExpression listExpression) {
+        List<ClassNode> list = new ArrayList<ClassNode>();
+        for (Expression itemExpr : listExpression.getExpressions()) {
+            if (itemExpr instanceof ClassExpression) {
+                ClassNode cn = itemExpr.getType();
+                if (cn != null) list.add(cn);
+            }
+        }
+        return list;
+    }
+
+    public void addError(String msg, ASTNode expr) {
+        sourceUnit.getErrorCollector().addErrorAndContinue(new SyntaxErrorMessage(
+                        new SyntaxException(msg + '\n', expr.getLineNumber(), expr.getColumnNumber(),
+                                expr.getLastLineNumber(), expr.getLastColumnNumber()),
+                        sourceUnit)
+        );
+    }
+
+    protected boolean checkNotInterface(ClassNode cNode, String annotationName) {
+        if (cNode.isInterface()) {
+            addError("Error processing interface '" + cNode.getName() + "'. " +
+                    annotationName + " not allowed for interfaces.", cNode);
+            return false;
+        }
+        return true;
+    }
+
+    public boolean hasAnnotation(ClassNode node, ClassNode annotation) {
+        return AnnotatedNodeUtils.hasAnnotation(node, annotation);
+    }
+
+    public static List<String> tokenize(String rawExcludes) {
+        return rawExcludes == null ? new ArrayList<String>() : StringGroovyMethods.tokenize(rawExcludes, ", ");
+    }
+
+    public static boolean deemedInternalName(String name) {
+        return name.contains("$");
+    }
+
+    public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes) {
+        return shouldSkipUndefinedAware(name, excludes, includes, false);
+    }
+
+    public static boolean shouldSkipUndefinedAware(String name, List<String> excludes, List<String> includes, boolean allNames) {
+        return (excludes != null && excludes.contains(name)) ||
+            (!allNames && deemedInternalName(name)) ||
+            (includes != null && !includes.contains(name));
+    }
+
+    public static boolean shouldSkip(String name, List<String> excludes, List<String> includes) {
+        return shouldSkip(name, excludes, includes, false);
+    }
+
+    public static boolean shouldSkip(String name, List<String> excludes, List<String> includes, boolean allNames) {
+        return (excludes != null && excludes.contains(name)) ||
+            (!allNames && deemedInternalName(name)) ||
+            (includes != null && !includes.isEmpty() && !includes.contains(name));
+    }
+
+    @Deprecated
+    public static boolean shouldSkipOnDescriptor(boolean checkReturn, Map genericsSpec, MethodNode mNode, List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
+        String descriptor = mNode.getTypeDescriptor();
+        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
+        for (ClassNode cn : excludeTypes) {
+            List<ClassNode> remaining = new LinkedList<ClassNode>();
+            remaining.add(cn);
+            Map updatedGenericsSpec = new HashMap(genericsSpec);
+            while (!remaining.isEmpty()) {
+                ClassNode next = remaining.remove(0);
+                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
+                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
+                    for (MethodNode mn : next.getMethods()) {
+                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
+                        if (checkReturn) {
+                            String md = correctedMethodNode.getTypeDescriptor();
+                            if (md.equals(descriptor)) return true;
+                        } else {
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
+                            if (md.equals(descriptorNoReturn)) return true;
+                        }
+                    }
+                    remaining.addAll(Arrays.asList(next.getInterfaces()));
+                }
+            }
+        }
+        if (includeTypes.isEmpty()) return false;
+        for (ClassNode cn : includeTypes) {
+            List<ClassNode> remaining = new LinkedList<ClassNode>();
+            remaining.add(cn);
+            Map updatedGenericsSpec = new HashMap(genericsSpec);
+            while (!remaining.isEmpty()) {
+                ClassNode next = remaining.remove(0);
+                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
+                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
+                    for (MethodNode mn : next.getMethods()) {
+                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
+                        if (checkReturn) {
+                            String md = correctedMethodNode.getTypeDescriptor();
+                            if (md.equals(descriptor)) return false;
+                        } else {
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
+                            if (md.equals(descriptorNoReturn)) return false;
+                        }
+                    }
+                    remaining.addAll(Arrays.asList(next.getInterfaces()));
+                }
+            }
+        }
+        return true;
+    }
+    public static boolean shouldSkipOnDescriptorUndefinedAware(boolean checkReturn, Map genericsSpec, MethodNode mNode,
+                                                  List<ClassNode> excludeTypes, List<ClassNode> includeTypes) {
+        String descriptor = mNode.getTypeDescriptor();
+        String descriptorNoReturn = MethodNodeUtils.methodDescriptorWithoutReturnType(mNode);
+        if (excludeTypes != null) {
+            for (ClassNode cn : excludeTypes) {
+                List<ClassNode> remaining = new LinkedList<ClassNode>();
+                remaining.add(cn);
+                Map updatedGenericsSpec = new HashMap(genericsSpec);
+                while (!remaining.isEmpty()) {
+                    ClassNode next = remaining.remove(0);
+                    if (!next.equals(ClassHelper.OBJECT_TYPE)) {
+                        updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
+                        for (MethodNode mn : next.getMethods()) {
+                            MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
+                            if (checkReturn) {
+                                String md = correctedMethodNode.getTypeDescriptor();
+                                if (md.equals(descriptor)) return true;
+                            } else {
+                                String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
+                                if (md.equals(descriptorNoReturn)) return true;
+                            }
+                        }
+                        remaining.addAll(Arrays.asList(next.getInterfaces()));
+                    }
+                }
+            }
+        }
+        if (includeTypes == null) return false;
+        for (ClassNode cn : includeTypes) {
+            List<ClassNode> remaining = new LinkedList<ClassNode>();
+            remaining.add(cn);
+            Map updatedGenericsSpec = new HashMap(genericsSpec);
+            while (!remaining.isEmpty()) {
+                ClassNode next = remaining.remove(0);
+                if (!next.equals(ClassHelper.OBJECT_TYPE)) {
+                    updatedGenericsSpec = GenericsUtils.createGenericsSpec(next, updatedGenericsSpec);
+                    for (MethodNode mn : next.getMethods()) {
+                        MethodNode correctedMethodNode = GenericsUtils.correctToGenericsSpec(updatedGenericsSpec, mn);
+                        if (checkReturn) {
+                            String md = correctedMethodNode.getTypeDescriptor();
+                            if (md.equals(descriptor)) return false;
+                        } else {
+                            String md = MethodNodeUtils.methodDescriptorWithoutReturnType(correctedMethodNode);
+                            if (md.equals(descriptorNoReturn)) return false;
+                        }
+                    }
+                    remaining.addAll(Arrays.asList(next.getInterfaces()));
+                }
+            }
+        }
+        return true;
+    }
+
+    @Deprecated
+    protected boolean checkIncludeExclude(AnnotationNode node, List<String> excludes, List<String> includes, String typeName) {
+        if (includes != null && !includes.isEmpty() && excludes != null && !excludes.isEmpty()) {
+            addError("Error during " + typeName + " processing: Only one of 'includes' and 'excludes' should be supplied not both.", node);
+            return false;
+        }
+        return true;
+    }
+
+    protected boolean checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes, String typeName) {
+        if (includes != null && excludes != null && !excludes.isEmpty()) {
+            addError("Error during " + typeName + " processing: Only one of 'includes' and 'excludes' should be supplied not both.", node);
+            return false;
+        }
+        return true;
+    }
+
+    @Deprecated
+    protected void checkIncludeExclude(AnnotationNode node, List<String> excludes, List<String> includes, List<ClassNode> excludeTypes, List<ClassNode> includeTypes, String typeName) {
+        int found = 0;
+        if (includes != null && !includes.isEmpty()) found++;
+        if (excludes != null && !excludes.isEmpty()) found++;
+        if (includeTypes != null && !includeTypes.isEmpty()) found++;
+        if (excludeTypes != null && !excludeTypes.isEmpty()) found++;
+        if (found > 1) {
+            addError("Error during " + typeName + " processing: Only one of 'includes', 'excludes', 'includeTypes' and 'excludeTypes' should be supplied.", node);
+        }
+    }
+
+    protected void checkIncludeExcludeUndefinedAware(AnnotationNode node, List<String> excludes, List<String> includes,
+                                        List<ClassNode> excludeTypes, List<ClassNode> includeTypes, String typeName) {
+        int found = 0;
+        if (includes != null) found++;
+        if (excludes != null && !excludes.isEmpty()) found++;
+        if (includeTypes != null) found++;
+        if (excludeTypes != null && !excludeTypes.isEmpty()) found++;
+        if (found > 1) {
+            addError("Error during " + typeName + " processing: Only one of 'includes', 'excludes', 'includeTypes' and 'excludeTypes' should be supplied.", node);
+        }
+    }
+
+    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields) {
+        return checkPropertyList(cNode, propertyNameList, listName, anno, typeName, includeFields, false, false);
+    }
+
+    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties) {
+        return checkPropertyList(cNode, propertyNameList, listName, anno, typeName, includeFields, includeSuperProperties, allProperties, false, false);
+    }
+
+    public boolean checkPropertyList(ClassNode cNode, List<String> propertyNameList, String listName, AnnotationNode anno, String typeName, boolean includeFields, boolean includeSuperProperties, boolean allProperties, boolean includeSuperFields, boolean includeStatic) {
+        if (propertyNameList == null || propertyNameList.isEmpty()) {
+            return true;
+        }
+        final List<String> pNames = new ArrayList<String>();
+        for (PropertyNode pNode : BeanUtils.getAllProperties(cNode, includeSuperProperties, includeStatic, allProperties)) {
+            pNames.add(pNode.getField().getName());
+        }
+        boolean result = true;
+        if (includeFields || includeSuperFields) {
+            final List<String> fNames = new ArrayList<String>();
+            if (includeFields) {
+                fNames.addAll(getInstanceNonPropertyFieldNames(cNode));
+            }
+            if (includeSuperFields) {
+                List<FieldNode> superNonPropertyFields = getSuperNonPropertyFields(cNode.getSuperClass());
+                for (FieldNode fn : superNonPropertyFields) {
+                    fNames.add(fn.getName());
+                }
+            }
+            for (String pName : propertyNameList) {
+                if (!pNames.contains(pName) && !fNames.contains(pName)) {
+                    addError("Error during " + typeName + " processing: '" + listName + "' property or field '" + pName + "' does not exist.", anno);
+                    result = false;
+                }
+            }
+        } else {
+            for (String pName : propertyNameList) {
+                if (!pNames.contains(pName)) {
+                    addError("Error during " + typeName + " processing: '" + listName + "' property '" + pName + "' does not exist.", anno);
+                    result = false;
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * @deprecated use GenericsUtils#nonGeneric
+     */
+    @Deprecated
+    public static ClassNode nonGeneric(ClassNode type) {
+        return GenericsUtils.nonGeneric(type);
+    }
+
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
index 27f242b..0cb9515 100644
--- a/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/FieldASTTransformation.java
@@ -1,292 +1,292 @@
-/*
- *  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;
-
-import groovy.cli.Option;
-import groovy.lang.Lazy;
-import groovy.transform.Field;
-import org.codehaus.groovy.GroovyBugError;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ConstructorNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.MethodNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.Variable;
-import org.codehaus.groovy.ast.VariableScope;
-import org.codehaus.groovy.ast.expr.ArgumentListExpression;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
-import org.codehaus.groovy.ast.expr.DeclarationExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.TupleExpression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.classgen.VariableScopeVisitor;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-import org.codehaus.groovy.runtime.MetaClassHelper;
-import org.objectweb.asm.Opcodes;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Iterator;
-import java.util.List;
-
-import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
-import static org.codehaus.groovy.ast.ClassHelper.make;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
-
-/**
- * Handles transformation for the @Field annotation.
- */
-@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
-public class FieldASTTransformation extends ClassCodeExpressionTransformer implements ASTTransformation, Opcodes {
-
-    private static final Class MY_CLASS = Field.class;
-    private static final ClassNode MY_TYPE = make(MY_CLASS);
-    private static final ClassNode LAZY_TYPE = make(Lazy.class);
-    private static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
-    private static final ClassNode ASTTRANSFORMCLASS_TYPE = make(GroovyASTTransformationClass.class);
-    private static final ClassNode OPTION_TYPE = make(Option.class);
-    private SourceUnit sourceUnit;
-    private DeclarationExpression candidate;
-    private boolean insideScriptBody;
-    private String variableName;
-    private FieldNode fieldNode;
-    private ClosureExpression currentClosure;
-    private ConstructorCallExpression currentAIC;
-
-    public void visit(ASTNode[] nodes, SourceUnit source) {
-        sourceUnit = source;
-        if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
-            throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
-        }
-
-        AnnotatedNode parent = (AnnotatedNode) nodes[1];
-        AnnotationNode node = (AnnotationNode) nodes[0];
-        if (!MY_TYPE.equals(node.getClassNode())) return;
-
-        if (parent instanceof DeclarationExpression) {
-            DeclarationExpression de = (DeclarationExpression) parent;
-            ClassNode cNode = de.getDeclaringClass();
-            if (!cNode.isScript()) {
-                addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
-                return;
-            }
-            candidate = de;
-            // GROOVY-4548: temp fix to stop CCE until proper support is added
-            if (de.isMultipleAssignmentDeclaration()) {
-                addError("Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", parent);
-                return;
-            }
-            VariableExpression ve = de.getVariableExpression();
-            variableName = ve.getName();
-            // set owner null here, it will be updated by addField
-            fieldNode = new FieldNode(variableName, ve.getModifiers(), ve.getType(), null, de.getRightExpression());
-            fieldNode.setSourcePosition(de);
-            cNode.addField(fieldNode);
-            // provide setter for CLI Builder purposes unless final
-            if (fieldNode.isFinal()) {
-                if (!de.getAnnotations(OPTION_TYPE).isEmpty()) {
-                    addError("Can't have a final field also annotated with @" + OPTION_TYPE.getNameWithoutPackage(), de);
-                }
-            } else {
-                String setterName = "set" + MetaClassHelper.capitalize(variableName);
-                cNode.addMethod(setterName, ACC_PUBLIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params(param(ve.getType(), variableName)), ClassNode.EMPTY_ARRAY, block(
-                        stmt(assignX(propX(varX("this"), variableName), varX(variableName)))
-                ));
-            }
-
-            // GROOVY-4833 : annotations that are not Groovy transforms should be transferred to the generated field
-            // GROOVY-6112 : also copy acceptable Groovy transforms
-            final List<AnnotationNode> annotations = de.getAnnotations();
-            for (AnnotationNode annotation : annotations) {
-                // GROOVY-6337 HACK: in case newly created field is @Lazy
-                if (annotation.getClassNode().equals(LAZY_TYPE)) {
-                    LazyASTTransformation.visitField(this, annotation, fieldNode);
-                }
-                final ClassNode annotationClassNode = annotation.getClassNode();
-                if (notTransform(annotationClassNode) || acceptableTransform(annotation)) {
-                    fieldNode.addAnnotation(annotation);
-                }
-            }
-
-            super.visitClass(cNode);
-            // GROOVY-5207 So that Closures can see newly added fields
-            // (not super efficient for a very large class with many @Fields but we chose simplicity
-            // and understandability of this solution over more complex but efficient alternatives)
-            VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
-            scopeVisitor.visitClass(cNode);
-        }
-    }
-
-    private static boolean acceptableTransform(AnnotationNode annotation) {
-        // TODO also check for phase after sourceUnit.getPhase()? but will be ignored anyway?
-        // TODO we should only copy those annotations with FIELD_TARGET but haven't visited annotations
-        // and gathered target info at this phase, so we can't do this:
-        // return annotation.isTargetAllowed(AnnotationNode.FIELD_TARGET);
-        // instead just don't copy ourselves for now
-        return !annotation.getClassNode().equals(MY_TYPE);
-    }
-
-    private static boolean notTransform(ClassNode annotationClassNode) {
-        return annotationClassNode.getAnnotations(ASTTRANSFORMCLASS_TYPE).isEmpty();
-    }
-
-    @Override
-    public Expression transform(Expression expr) {
-        if (expr == null) return null;
-        if (expr instanceof DeclarationExpression) {
-            DeclarationExpression de = (DeclarationExpression) expr;
-            if (de.getLeftExpression() == candidate.getLeftExpression()) {
-                if (insideScriptBody) {
-                    // TODO make EmptyExpression work
-                    // partially works but not if only thing in script
-                    // return EmptyExpression.INSTANCE;
-                    return new ConstantExpression(null);
-                }
-                addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script body.", expr);
-                return expr;
-            }
-        } else if (insideScriptBody && expr instanceof VariableExpression && currentClosure != null) {
-            VariableExpression ve = (VariableExpression) expr;
-            if (ve.getName().equals(variableName)) {
-                adjustToClassVar(ve);
-                return ve;
-            }
-        } else if (currentAIC != null && expr instanceof ArgumentListExpression) {
-            // if a match is found, the compiler will have already set up aic constructor to hav
-            // an argument which isn't needed since we'll be accessing the field; we must undo it
-            Expression skip = null;
-            List<Expression> origArgList = ((ArgumentListExpression) expr).getExpressions();
-            for (int i = 0; i < origArgList.size(); i++) {
-                Expression arg = origArgList.get(i);
-                if (matchesCandidate(arg)) {
-                    skip = arg;
-                    adjustConstructorAndFields(i, currentAIC.getType());
-                    break;
-                }
-            }
-            if (skip != null) {
-                return adjustedArgList(skip, origArgList);
-            }
-        }
-        return expr.transformExpression(this);
-    }
-
-    private boolean matchesCandidate(Expression arg) {
-        return arg instanceof VariableExpression && ((VariableExpression) arg).getAccessedVariable() == candidate.getVariableExpression().getAccessedVariable();
-    }
-
-    private Expression adjustedArgList(Expression skip, List<Expression> origArgs) {
-        List<Expression> newArgs = new ArrayList<Expression>(origArgs.size() - 1);
-        for (Expression origArg : origArgs) {
-            if (skip != origArg) {
-                newArgs.add(origArg);
-            }
-        }
-        return new ArgumentListExpression(newArgs);
-    }
-
-    private void adjustConstructorAndFields(int skipIndex, ClassNode type) {
-        List<ConstructorNode> constructors = type.getDeclaredConstructors();
-        if (constructors.size() == 1) {
-            ConstructorNode constructor = constructors.get(0);
-            Parameter[] params = constructor.getParameters();
-            Parameter[] newParams = new Parameter[params.length - 1];
-            int to = 0;
-            for (int from = 0; from < params.length; from++) {
-                if (from != skipIndex) {
-                    newParams[to++] = params[from];
-                }
-            }
-            type.removeConstructor(constructor);
-            // code doesn't mention the removed param at this point, okay to leave as is
-            addGeneratedConstructor(type, constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode());
-            type.removeField(variableName);
-        }
-    }
-
-    private void adjustToClassVar(VariableExpression expr) {
-        // we only need to check the variable name because the Groovy compiler
-        // already fails if a variable with the same name already exists in the scope.
-        // this means that a closure cannot shadow a class variable
-        expr.setAccessedVariable(fieldNode);
-        final VariableScope variableScope = currentClosure.getVariableScope();
-        final Iterator<Variable> iterator = variableScope.getReferencedLocalVariablesIterator();
-        while (iterator.hasNext()) {
-            Variable next = iterator.next();
-            if (next.getName().equals(variableName)) iterator.remove();
-        }
-        variableScope.putReferencedClassVariable(fieldNode);
-    }
-
-    @Override
-    public void visitClosureExpression(final ClosureExpression expression) {
-        ClosureExpression old = currentClosure;
-        currentClosure = expression;
-        super.visitClosureExpression(expression);
-        currentClosure = old;
-    }
-
-    @Override
-    public void visitConstructorCallExpression(final ConstructorCallExpression cce) {
-        if (!insideScriptBody || !cce.isUsingAnonymousInnerClass()) return;
-        ConstructorCallExpression old = currentAIC;
-        currentAIC = cce;
-        Expression newArgs = transform(cce.getArguments());
-        if (cce.getArguments() instanceof TupleExpression && newArgs instanceof TupleExpression) {
-            List<Expression> argList = ((TupleExpression) cce.getArguments()).getExpressions();
-            argList.clear();
-            argList.addAll(((TupleExpression) newArgs).getExpressions());
-        }
-        currentAIC = old;
-    }
-
-    @Override
-    public void visitMethod(MethodNode node) {
-        Boolean oldInsideScriptBody = insideScriptBody;
-        if (node.isScriptBody()) insideScriptBody = true;
-        super.visitMethod(node);
-        insideScriptBody = oldInsideScriptBody;
-    }
-
-    @Override
-    public void visitExpressionStatement(ExpressionStatement es) {
-        Expression exp = es.getExpression();
-        exp.visit(this);
-        super.visitExpressionStatement(es);
-    }
-
-    protected SourceUnit getSourceUnit() {
-        return sourceUnit;
-    }
-}
+/*
+ *  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;
+
+import groovy.cli.Option;
+import groovy.lang.Lazy;
+import groovy.transform.Field;
+import org.codehaus.groovy.GroovyBugError;
+import org.codehaus.groovy.ast.ASTNode;
+import org.codehaus.groovy.ast.AnnotatedNode;
+import org.codehaus.groovy.ast.AnnotationNode;
+import org.codehaus.groovy.ast.ClassCodeExpressionTransformer;
+import org.codehaus.groovy.ast.ClassHelper;
+import org.codehaus.groovy.ast.ClassNode;
+import org.codehaus.groovy.ast.ConstructorNode;
+import org.codehaus.groovy.ast.FieldNode;
+import org.codehaus.groovy.ast.MethodNode;
+import org.codehaus.groovy.ast.Parameter;
+import org.codehaus.groovy.ast.Variable;
+import org.codehaus.groovy.ast.VariableScope;
+import org.codehaus.groovy.ast.expr.ArgumentListExpression;
+import org.codehaus.groovy.ast.expr.ClosureExpression;
+import org.codehaus.groovy.ast.expr.ConstantExpression;
+import org.codehaus.groovy.ast.expr.ConstructorCallExpression;
+import org.codehaus.groovy.ast.expr.DeclarationExpression;
+import org.codehaus.groovy.ast.expr.Expression;
+import org.codehaus.groovy.ast.expr.TupleExpression;
+import org.codehaus.groovy.ast.expr.VariableExpression;
+import org.codehaus.groovy.ast.stmt.ExpressionStatement;
+import org.codehaus.groovy.classgen.VariableScopeVisitor;
+import org.codehaus.groovy.control.CompilePhase;
+import org.codehaus.groovy.control.SourceUnit;
+import org.codehaus.groovy.runtime.MetaClassHelper;
+import org.objectweb.asm.Opcodes;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import static org.apache.groovy.ast.tools.ClassNodeUtils.addGeneratedConstructor;
+import static org.codehaus.groovy.ast.ClassHelper.make;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.assignX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.param;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
+import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
+
+/**
+ * Handles transformation for the @Field annotation.
+ */
+@GroovyASTTransformation(phase = CompilePhase.SEMANTIC_ANALYSIS)
+public class FieldASTTransformation extends ClassCodeExpressionTransformer implements ASTTransformation, Opcodes {
+
+    private static final Class MY_CLASS = Field.class;
+    private static final ClassNode MY_TYPE = make(MY_CLASS);
+    private static final ClassNode LAZY_TYPE = make(Lazy.class);
+    private static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
+    private static final ClassNode ASTTRANSFORMCLASS_TYPE = make(GroovyASTTransformationClass.class);
+    private static final ClassNode OPTION_TYPE = make(Option.class);
+    private SourceUnit sourceUnit;
+    private DeclarationExpression candidate;
+    private boolean insideScriptBody;
+    private String variableName;
+    private FieldNode fieldNode;
+    private ClosureExpression currentClosure;
+    private ConstructorCallExpression currentAIC;
+
+    public void visit(ASTNode[] nodes, SourceUnit source) {
+        sourceUnit = source;
+        if (nodes.length != 2 || !(nodes[0] instanceof AnnotationNode) || !(nodes[1] instanceof AnnotatedNode)) {
+            throw new GroovyBugError("Internal error: expecting [AnnotationNode, AnnotatedNode] but got: " + Arrays.asList(nodes));
+        }
+
+        AnnotatedNode parent = (AnnotatedNode) nodes[1];
+        AnnotationNode node = (AnnotationNode) nodes[0];
+        if (!MY_TYPE.equals(node.getClassNode())) return;
+
+        if (parent instanceof DeclarationExpression) {
+            DeclarationExpression de = (DeclarationExpression) parent;
+            ClassNode cNode = de.getDeclaringClass();
+            if (!cNode.isScript()) {
+                addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
+                return;
+            }
+            candidate = de;
+            // GROOVY-4548: temp fix to stop CCE until proper support is added
+            if (de.isMultipleAssignmentDeclaration()) {
+                addError("Annotation " + MY_TYPE_NAME + " not supported with multiple assignment notation.", parent);
+                return;
+            }
+            VariableExpression ve = de.getVariableExpression();
+            variableName = ve.getName();
+            // set owner null here, it will be updated by addField
+            fieldNode = new FieldNode(variableName, ve.getModifiers(), ve.getType(), null, de.getRightExpression());
+            fieldNode.setSourcePosition(de);
+            cNode.addField(fieldNode);
+            // provide setter for CLI Builder purposes unless final
+            if (fieldNode.isFinal()) {
+                if (!de.getAnnotations(OPTION_TYPE).isEmpty()) {
+                    addError("Can't have a final field also annotated with @" + OPTION_TYPE.getNameWithoutPackage(), de);
+                }
+            } else {
+                String setterName = "set" + MetaClassHelper.capitalize(variableName);
+                cNode.addMethod(setterName, ACC_PUBLIC | ACC_SYNTHETIC, ClassHelper.VOID_TYPE, params(param(ve.getType(), variableName)), ClassNode.EMPTY_ARRAY, block(
+                        stmt(assignX(propX(varX("this"), variableName), varX(variableName)))
+                ));
+            }
+
+            // GROOVY-4833 : annotations that are not Groovy transforms should be transferred to the generated field
+            // GROOVY-6112 : also copy acceptable Groovy transforms
+            final List<AnnotationNode> annotations = de.getAnnotations();
+            for (AnnotationNode annotation : annotations) {
+                // GROOVY-6337 HACK: in case newly created field is @Lazy
+                if (annotation.getClassNode().equals(LAZY_TYPE)) {
+                    LazyASTTransformation.visitField(this, annotation, fieldNode);
+                }
+                final ClassNode annotationClassNode = annotation.getClassNode();
+                if (notTransform(annotationClassNode) || acceptableTransform(annotation)) {
+                    fieldNode.addAnnotation(annotation);
+                }
+            }
+
+            super.visitClass(cNode);
+            // GROOVY-5207 So that Closures can see newly added fields
+            // (not super efficient for a very large class with many @Fields but we chose simplicity
+            // and understandability of this solution over more complex but efficient alternatives)
+            VariableScopeVisitor scopeVisitor = new VariableScopeVisitor(source);
+            scopeVisitor.visitClass(cNode);
+        }
+    }
+
+    private static boolean acceptableTransform(AnnotationNode annotation) {
+        // TODO also check for phase after sourceUnit.getPhase()? but will be ignored anyway?
+        // TODO we should only copy those annotations with FIELD_TARGET but haven't visited annotations
+        // and gathered target info at this phase, so we can't do this:
+        // return annotation.isTargetAllowed(AnnotationNode.FIELD_TARGET);
+        // instead just don't copy ourselves for now
+        return !annotation.getClassNode().equals(MY_TYPE);
+    }
+
+    private static boolean notTransform(ClassNode annotationClassNode) {
+        return annotationClassNode.getAnnotations(ASTTRANSFORMCLASS_TYPE).isEmpty();
+    }
+
+    @Override
+    public Expression transform(Expression expr) {
+        if (expr == null) return null;
+        if (expr instanceof DeclarationExpression) {
+            DeclarationExpression de = (DeclarationExpression) expr;
+            if (de.getLeftExpression() == candidate.getLeftExpression()) {
+                if (insideScriptBody) {
+                    // TODO make EmptyExpression work
+                    // partially works but not if only thing in script
+                    // return EmptyExpression.INSTANCE;
+                    return new ConstantExpression(null);
+                }
+                addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script body.", expr);
+                return expr;
+            }
+        } else if (insideScriptBody && expr instanceof VariableExpression && currentClosure != null) {
+            VariableExpression ve = (VariableExpression) expr;
+            if (ve.getName().equals(variableName)) {
+                adjustToClassVar(ve);
+                return ve;
+            }
+        } else if (currentAIC != null && expr instanceof ArgumentListExpression) {
+            // if a match is found, the compiler will have already set up aic constructor to hav
+            // an argument which isn't needed since we'll be accessing the field; we must undo it
+            Expression skip = null;
+            List<Expression> origArgList = ((ArgumentListExpression) expr).getExpressions();
+            for (int i = 0; i < origArgList.size(); i++) {
+                Expression arg = origArgList.get(i);
+                if (matchesCandidate(arg)) {
+                    skip = arg;
+                    adjustConstructorAndFields(i, currentAIC.getType());
+                    break;
+                }
+            }
+            if (skip != null) {
+                return adjustedArgList(skip, origArgList);
+            }
+        }
+        return expr.transformExpression(this);
+    }
+
+    private boolean matchesCandidate(Expression arg) {
+        return arg instanceof VariableExpression && ((VariableExpression) arg).getAccessedVariable() == candidate.getVariableExpression().getAccessedVariable();
+    }
+
+    private Expression adjustedArgList(Expression skip, List<Expression> origArgs) {
+        List<Expression> newArgs = new ArrayList<Expression>(origArgs.size() - 1);
+        for (Expression origArg : origArgs) {
+            if (skip != origArg) {
+                newArgs.add(origArg);
+            }
+        }
+        return new ArgumentListExpression(newArgs);
+    }
+
+    private void adjustConstructorAndFields(int skipIndex, ClassNode type) {
+        List<ConstructorNode> constructors = type.getDeclaredConstructors();
+        if (constructors.size() == 1) {
+            ConstructorNode constructor = constructors.get(0);
+            Parameter[] params = constructor.getParameters();
+            Parameter[] newParams = new Parameter[params.length - 1];
+            int to = 0;
+            for (int from = 0; from < params.length; from++) {
+                if (from != skipIndex) {
+                    newParams[to++] = params[from];
+                }
+            }
+            type.removeConstructor(constructor);
+            // code doesn't mention the removed param at this point, okay to leave as is
+            addGeneratedConstructor(type, constructor.getModifiers(), newParams, constructor.getExceptions(), constructor.getCode());
+            type.removeField(variableName);
+        }
+    }
+
+    private void adjustToClassVar(VariableExpression expr) {
+        // we only need to check the variable name because the Groovy compiler
+        // already fails if a variable with the same name already exists in the scope.
+        // this means that a closure cannot shadow a class variable
+        expr.setAccessedVariable(fieldNode);
+        final VariableScope variableScope = currentClosure.getVariableScope();
+        final Iterator<Variable> iterator = variableScope.getReferencedLocalVariablesIterator();
+        while (iterator.hasNext()) {
+            Variable next = iterator.next();
+            if (next.getName().equals(variableName)) iterator.remove();
+        }
+        variableScope.putReferencedClassVariable(fieldNode);
+    }
+
+    @Override
+    public void visitClosureExpression(final ClosureExpression expression) {
+        ClosureExpression old = currentClosure;
+        currentClosure = expression;
+        super.visitClosureExpression(expression);
+        currentClosure = old;
+    }
+
+    @Override
+    public void visitConstructorCallExpression(final ConstructorCallExpression cce) {
+        if (!insideScriptBody || !cce.isUsingAnonymousInnerClass()) return;
+        ConstructorCallExpression old = currentAIC;
+        currentAIC = cce;
+        Expression newArgs = transform(cce.getArguments());
+        if (cce.getArguments() instanceof TupleExpression && newArgs instanceof TupleExpression) {
+            List<Expression> argList = ((TupleExpression) cce.getArguments()).getExpressions();
+            argList.clear();
+            argList.addAll(((TupleExpression) newArgs).getExpressions());
+        }
+        currentAIC = old;
+    }
+
+    @Override
+    public void visitMethod(MethodNode node) {
+        Boolean oldInsideScriptBody = insideScriptBody;
+        if (node.isScriptBody()) insideScriptBody = true;
+        super.visitMethod(node);
+        insideScriptBody = oldInsideScriptBody;
+    }
+
+    @Override
+    public void visitExpressionStatement(ExpressionStatement es) {
+        Expression exp = es.getExpression();
+        exp.visit(this);
+        super.visitExpressionStatement(es);
+    }
+
+    protected SourceUnit getSourceUnit() {
+        return sourceUnit;
+    }
+}
diff --git a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
index 1748eb6..8dd0f7a 100644
--- a/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
+++ b/src/main/java/org/codehaus/groovy/transform/TupleConstructorASTTransformation.java
@@ -1,353 +1,353 @@
-/*
- *  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;
-
-import groovy.lang.GroovyClassLoader;
-import groovy.transform.CompilationUnitAware;
-import groovy.transform.MapConstructor;
-import groovy.transform.TupleConstructor;
-import groovy.transform.options.PropertyHandler;
-import org.apache.groovy.ast.tools.AnnotatedNodeUtils;
-import org.codehaus.groovy.ast.ASTNode;
-import org.codehaus.groovy.ast.AnnotatedNode;
-import org.codehaus.groovy.ast.AnnotationNode;
-import org.codehaus.groovy.ast.ClassHelper;
-import org.codehaus.groovy.ast.ClassNode;
-import org.codehaus.groovy.ast.ConstructorNode;
-import org.codehaus.groovy.ast.FieldNode;
-import org.codehaus.groovy.ast.Parameter;
-import org.codehaus.groovy.ast.PropertyNode;
-import org.codehaus.groovy.ast.expr.ClosureExpression;
-import org.codehaus.groovy.ast.expr.ConstantExpression;
-import org.codehaus.groovy.ast.expr.Expression;
-import org.codehaus.groovy.ast.expr.VariableExpression;
-import org.codehaus.groovy.ast.stmt.BlockStatement;
-import org.codehaus.groovy.ast.stmt.EmptyStatement;
-import org.codehaus.groovy.ast.stmt.ExpressionStatement;
-import org.codehaus.groovy.ast.stmt.Statement;
-import org.codehaus.groovy.classgen.VariableScopeVisitor;
-import org.codehaus.groovy.control.CompilationUnit;
-import org.codehaus.groovy.control.CompilePhase;
-import org.codehaus.groovy.control.SourceUnit;
-
-import java.lang.annotation.Annotation;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import static org.apache.groovy.ast.tools.AnnotatedNodeUtils.markAsGenerated;
-import static org.apache.groovy.ast.tools.ClassNodeUtils.hasExplicitConstructor;
-import static org.apache.groovy.ast.tools.VisibilityUtils.getVisibility;
-import static org.codehaus.groovy.ast.ClassHelper.make;
-import static org.codehaus.groovy.ast.ClassHelper.makeWithoutCaching;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.args;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.assignS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.block;
-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.copyStatementsWithSuperAdjustment;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ctorX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.equalsNullX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.getAllProperties;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ifElseS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.ifS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.params;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.propX;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.stmt;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.throwS;
-import static org.codehaus.groovy.ast.tools.GeneralUtils.varX;
-import static org.codehaus.groovy.transform.ImmutableASTTransformation.makeImmutable;
-
-/**
- * Handles generation of code for the @TupleConstructor annotation.
- */
-@GroovyASTTransformation(phase = CompilePhase.CANONICALIZATION)
-public class TupleConstructorASTTransformation extends AbstractASTTransformation implements CompilationUnitAware {
-
-    private CompilationUnit compilationUnit;
-    static final Class MY_CLASS = TupleConstructor.class;
-    static final ClassNode MY_TYPE = make(MY_CLASS);
-    static final String MY_TYPE_NAME = "@" + MY_TYPE.getNameWithoutPackage();
-    private static final ClassNode LHMAP_TYPE = makeWithoutCaching(LinkedHashMap.class, false);
-    private static final ClassNode CHECK_METHOD_TYPE = make(ImmutableASTTransformation.class);
-    private static final Class<? extends Annotation> MAP_CONSTRUCTOR_CLASS = MapConstructor.class;
-    private static final Map<Class<?>, Expression> primitivesInitialValues;
-
-    static {
-        final ConstantExpression zero = constX(0);
-        final ConstantExpression zeroDecimal = constX(.0);
-        primitivesInitialValues = new HashMap<Class<?>, Expression>();
-        primitivesInitialValues.put(int.class, zero);
-        primitivesInitialValues.put(long.class, zero);
-        primitivesInitialValues.put(short.class, zero);
-        primitivesInitialValues.put(byte.class, zero);
-        primitivesInitialValues.put(char.class, zero);
-        primitivesInitialValues.put(float.class, zeroDecimal);
-        primitivesInitialValues.put(double.class, zeroDecimal);
-        primitivesInitialValues.put(boolean.class, ConstantExpression.FALSE);
-    }
-
-    @Override
-    public String getAnnotationName() {
-        return MY_TYPE_NAME;
-    }
-
-    public void visit(ASTNode[] nodes, SourceUnit source) {
-        init(nodes, source);
-        AnnotatedNode parent = (AnnotatedNode) nodes[1];
-        AnnotationNode anno = (AnnotationNode) nodes[0];
-        if (!MY_TYPE.equals(anno.getClassNode())) return;
-
-        if (parent instanceof ClassNode) {
-            ClassNode cNode = (ClassNode) parent;
-            if (!checkNotInterface(cNode, MY_TYPE_NAME)) return;
-            boolean includeFields = memberHasValue(anno, "includeFields", true);
-            boolean includeProperties = !memberHasValue(anno, "includeProperties", false);
-            boolean includeSuperFields = memberHasValue(anno, "includeSuperFields", true);
-            boolean includeSuperProperties = memberHasValue(anno, "includeSuperProperties", true);
-            boolean allProperties = memberHasValue(anno, "allProperties", true);
-            List<String> excludes = getMemberStringList(anno, "excludes");
-            List<String> includes = getMemberStringList(anno, "includes");
-            boolean allNames = memberHasValue(anno, "allNames", true);
-            if (!checkIncludeExcludeUndefinedAware(anno, excludes, includes, MY_TYPE_NAME)) return;
-            if (!checkPropertyList(cNode, includes, "includes", anno, MY_TYPE_NAME, includeFields, includeSuperProperties, allProperties, includeSuperFields, false))
-                return;
-            if (!checkPropertyList(cNode, excludes, "excludes", anno, MY_TYPE_NAME, includeFields, includeSuperProperties, allProperties, includeSuperFields, false))
-                return;
-            final GroovyClassLoader classLoader = compilationUnit != null ? compilationUnit.getTransformLoader() : source.getClassLoader();
-            final PropertyHandler handler = PropertyHandler.createPropertyHandler(this, classLoader, cNode);
-            if (handler == null) return;
-            if (!handler.validateAttributes(this, anno)) return;
-
-            Expression pre = anno.getMember("pre");
-            if (pre != null && !(pre instanceof ClosureExpression)) {
-                addError("Expected closure value for annotation parameter 'pre'. Found " + pre, cNode);
-                return;
-            }
-            Expression post = anno.getMember("post");
-            if (post != null && !(post instanceof ClosureExpression)) {
-                addError("Expected closure value for annotation parameter 'post'. Found " + post, cNode);
-                return;
-            }
-
-            createConstructor(this, anno, cNode, includeFields, includeProperties, includeSuperFields, includeSuperProperties,
-                    excludes, includes, allNames, allProperties,
-                    sourceUnit, handler, (ClosureExpression) pre, (ClosureExpression) post);
-
-            if (pre != null) {
-                anno.setMember("pre", new ClosureExpression(Parameter.EMPTY_ARRAY, EmptyStatement.INSTANCE));
-            }
-            if (post != null) {
-                anno.setMember("post", new ClosureExpression(Parameter.EMPTY_ARRAY, EmptyStatement.INSTANCE));
-            }
-        }
-    }
-
-    private static void createConstructor(AbstractASTTransformation xform, AnnotationNode anno, ClassNode cNode, boolean includeFields,
-                                          boolean includeProperties, boolean includeSuperFields, boolean includeSuperProperties,
-                                          List<String> excludes, final List<String> includes, boolean allNames, boolean allProperties,
-                                          SourceUnit sourceUnit, PropertyHandler handler, ClosureExpression pre, ClosureExpression post) {
-        boolean callSuper = xform.memberHasValue(anno, "callSuper", true);
-        boolean force = xform.memberHasValue(anno, "force", true);
-        boolean defaults = !xform.memberHasValue(anno, "defaults", false);
-        Set<String> names = new HashSet<String>();
-        List<PropertyNode> superList;
-        if (includeSuperProperties || includeSuperFields) {
-            superList = getAllProperties(names, cNode.getSuperClass(), includeSuperProperties, includeSuperFields, false, allProperties, true, true);
-        } else {
-            superList = new ArrayList<PropertyNode>();
-        }
-
-        List<PropertyNode> list = getAllProperties(names, cNode, includeProperties, includeFields, false, allProperties, false, true);
-
-        boolean makeImmutable = makeImmutable(cNode);
-        boolean specialNamedArgCase = (ImmutableASTTransformation.isSpecialNamedArgCase(list, !defaults) && superList.isEmpty()) ||
-                (ImmutableASTTransformation.isSpecialNamedArgCase(superList, !defaults) && list.isEmpty());
-
-        // no processing if existing constructors found unless forced or ImmutableBase in play
-        if (hasExplicitConstructor(null, cNode) && !force && !makeImmutable) return;
-
-        final List<Parameter> params = new ArrayList<Parameter>();
-        final List<Expression> superParams = new ArrayList<Expression>();
-        final BlockStatement preBody = new BlockStatement();
-        boolean superInPre = false;
-        if (pre != null) {
-            superInPre = copyStatementsWithSuperAdjustment(pre, preBody);
-            if (superInPre && callSuper) {
-                xform.addError("Error during " + MY_TYPE_NAME + " processing, can't have a super call in 'pre' " +
-                        "closure and also 'callSuper' enabled", cNode);
-            }
-        }
-
-        final BlockStatement body = new BlockStatement();
-
-        List<PropertyNode> tempList = new ArrayList<PropertyNode>(list);
-        tempList.addAll(superList);
-        if (!handler.validateProperties(xform, body, cNode, tempList)) {
-            return;
-        }
-
-        for (PropertyNode pNode : superList) {
-            String name = pNode.getName();
-            FieldNode fNode = pNode.getField();
-            if (shouldSkipUndefinedAware(name, excludes, includes, allNames)) continue;
-            params.add(createParam(fNode, name, defaults, xform, makeImmutable));
-            if (callSuper) {
... 43622 lines suppressed ...