anchor.diff:  You won't be able to use any of the new language features with the old parser.
   The old parser is deprecated and will be removed in Groovy 4.
   |===
  +
  +[[Groovy3.0releasenotes-GDKimprovements]]
  +== GDK improvements
  +
  +Groovy adds many extension methods to existing Java classes. In Groovy 3, about 80 new such extension methods were added.
  +We highlight just a few here:
  +
  +=== `average()` on arrays and iterables
  +
  +[source,groovy]
  +--------------------------------------
  +assert 3 == [1, 2, 6].average()
  +--------------------------------------
  +
  +=== `takeBetween()` on Strings, CharSequences and GStrings
  +
  +[source,groovy]
  +--------------------------------------
  +assert 'Groovy'.takeBetween( 'r', 'v' ) == 'oo'
  +--------------------------------------
  +
  +=== `shuffle()` and `shuffled()` on arrays and iterables
  +
  +[source,groovy]
  +--------------------------------------
  +def orig = [1, 3, 5, 7]
  +def mixed = orig.shuffled()
  +assert mixed.size() == orig.size()
  +assert mixed.toString() ==~ /\[(\d, ){3}\d\]/
  +--------------------------------------
  +
  +=== `collect{ }` on `Future`
  +
  +[source,groovy]
  +--------------------------------------
  +Future<String> foobar = executor.submit{ "foobar" }
  +Future<Integer> foobarSize = foobar.collect{ it.size() } // async
  +assert foobarSize.get() == 6
  +--------------------------------------
  +
  +=== `minus()` on `LocalDate`
  +
  +[source,groovy]
  +--------------------------------------
  +def xmas = LocalDate.of(2019, Month.DECEMBER, 25)
  +def newYear = LocalDate.of(2020, Month.JANUARY, 1)
  +assert newYear - xmas == 7 // a week apart
  +--------------------------------------
  +
  +[[Groovy3.0releasenotes-Miscimprovements]]
  +== Miscellaneous improvements
  +
  +=== Embedded Groovydoc
  +
  +You can now embed Groovydoc comments in various ways:
  +
  +* They can be made available within the AST for use by AST transformations and other tools.
  +Our revamped groovydoc tool (still under development) is based on this capability.
  +Behind the scenes the groovydoc content is stored as node metadata but a simple API
  +hides this implementation detail.
  +This feature is enabled using the `groovy.attach.groovydoc` system property or
  +corresponding flag in `CompilerConfiguration`.
  +
  +* Groovydoc comments starting with a special `/**@` opening comment delimiter can also be embedded into the class file
  +(behind the scenes it's stored in a @Groovydoc annotation) and is available at runtime for access
  +via reflection or via other tools. This is enabled using the `groovy.attach.runtime.groovydoc` system
  +property or corresponding flag in `CompilerConfiguration`. This provides a capability in Groovy inspired
  +by languages like Ruby which can embed documentation into the standard binary jar and is thus always available
  +rather than relying on a separate javadoc jar.
  +
  +Here is an example illustrating access to groovydoc comments within the AST:
  +
  +[source,groovy]
  +--------------------------------------
  +import org.codehaus.groovy.control.*
  +
  +def cc = new CompilerConfiguration(optimizationOptions:
  +    [(CompilerConfiguration.GROOVYDOC): true])
  +
  +def ast = new CompilationUnit(cc).tap {
  +    addSource 'myScript.groovy', '''
  +        /** class doco */
  +        class MyClass {
  +            /** method doco */
  +            def myMethod() {}
  +        }
  +    '''
  +    compile Phases.SEMANTIC_ANALYSIS
  +}.ast
  +
  +def classDoc = ast.classes[0].groovydoc
  +assert classDoc.content.contains('class doco')
  +def methodDoc = ast.classes[0].methods[0].groovydoc
  +assert methodDoc.content.contains('method doco')
  +--------------------------------------
  +
  +Here is an example using illustrating runtime groovydoc (with and without the flag set):
  +
  +[source,groovy]
  +--------------------------------------
  +import org.codehaus.groovy.control.*
  +
  +def extract(shell) {
  +    shell.evaluate( '''
  +        /**@
  +         * Some class groovydoc for Foo
  +         */
  +        class Foo {}
  +        Foo.class
  +        '''
  +    ).groovydoc.content.replaceAll('[^\\w\\s]', '').trim()
  +}
  +
  +// first without the flag set
  +assert extract(new GroovyShell()) == ''
  +
  +// now with embedding turned on
  +def cc = new CompilerConfiguration(optimizationOptions:
  +    [(CompilerConfiguration.RUNTIME_GROOVYDOC): true])
  +assert extract(new GroovyShell(cc)) == 'Some class groovydoc for Foo'
  +--------------------------------------
  +
  +=== JSR308 improvements (work in progress)
  +
  +Groovy has been improving JSR-308 support over recent versions.
  +As part of implementing the new grammar, additional support has been added.
   
   [[Groovy3.0releasenotes-Splitpackages]]
   == Split package changes (from beta-2)
  
positive.code: |
  |===
  
  [[Groovy3.0releasenotes-GDKimprovements]]
  == GDK improvements
  
  Groovy adds many extension methods to existing Java classes. In Groovy 3, about 80 new such extension methods were added.
  We highlight just a few here:
  
  === `average()` on arrays and iterables
  
  [source,groovy]
  --------------------------------------
  assert 3 == [1, 2, 6].average()
  --------------------------------------
  
  === `takeBetween()` on Strings, CharSequences and GStrings
  
  [source,groovy]
  --------------------------------------
  assert 'Groovy'.takeBetween( 'r', 'v' ) == 'oo'
  --------------------------------------
  
  === `shuffle()` and `shuffled()` on arrays and iterables
  
  [source,groovy]
  --------------------------------------
  def orig = [1, 3, 5, 7]
  def mixed = orig.shuffled()
  assert mixed.size() == orig.size()
  assert mixed.toString() ==~ /\[(\d, ){3}\d\]/
  --------------------------------------
  
  === `collect{ }` on `Future`
  
  [source,groovy]
  --------------------------------------
  Future<String> foobar = executor.submit{ "foobar" }
  Future<Integer> foobarSize = foobar.collect{ it.size() } // async
  assert foobarSize.get() == 6
  --------------------------------------
  
  === `minus()` on `LocalDate`
  
  [source,groovy]
  --------------------------------------
  def xmas = LocalDate.of(2019, Month.DECEMBER, 25)
  def newYear = LocalDate.of(2020, Month.JANUARY, 1)
  assert newYear - xmas == 7 // a week apart
  --------------------------------------
  
  [[Groovy3.0releasenotes-Miscimprovements]]
  == Miscellaneous improvements
  
  === Embedded Groovydoc
  
  You can now embed Groovydoc comments in various ways:
  
  * They can be made available within the AST for use by AST transformations and other tools.
  Our revamped groovydoc tool (still under development) is based on this capability.
  Behind the scenes the groovydoc content is stored as node metadata but a simple API
  hides this implementation detail.
  This feature is enabled using the `groovy.attach.groovydoc` system property or
  corresponding flag in `CompilerConfiguration`.
  
  * Groovydoc comments starting with a special `/**@` opening comment delimiter can also be embedded into the class file
  (behind the scenes it's stored in a @Groovydoc annotation) and is available at runtime for access
  via reflection or via other tools. This is enabled using the `groovy.attach.runtime.groovydoc` system
  property or corresponding flag in `CompilerConfiguration`. This provides a capability in Groovy inspired
  by languages like Ruby which can embed documentation into the standard binary jar and is thus always available
  rather than relying on a separate javadoc jar.
  
  Here is an example illustrating access to groovydoc comments within the AST:
  
  [source,groovy]
  --------------------------------------
  import org.codehaus.groovy.control.*
  
  def cc = new CompilerConfiguration(optimizationOptions:
      [(CompilerConfiguration.GROOVYDOC): true])
  
  def ast = new CompilationUnit(cc).tap {
      addSource 'myScript.groovy', '''
          /** class doco */
          class MyClass {
              /** method doco */
              def myMethod() {}
          }
      '''
      compile Phases.SEMANTIC_ANALYSIS
  }.ast
  
  def classDoc = ast.classes[0].groovydoc
  assert classDoc.content.contains('class doco')
  def methodDoc = ast.classes[0].methods[0].groovydoc
  assert methodDoc.content.contains('method doco')
  --------------------------------------
  
  Here is an example using illustrating runtime groovydoc (with and without the flag set):
  
  [source,groovy]
  --------------------------------------
  import org.codehaus.groovy.control.*
  
  def extract(shell) {
      shell.evaluate( '''
          /**@
           * Some class groovydoc for Foo
           */
          class Foo {}
          Foo.class
          '''
      ).groovydoc.content.replaceAll('[^\\w\\s]', '').trim()
  }
  
  // first without the flag set
  assert extract(new GroovyShell()) == ''
  
  // now with embedding turned on
  def cc = new CompilerConfiguration(optimizationOptions:
      [(CompilerConfiguration.RUNTIME_GROOVYDOC): true])
  assert extract(new GroovyShell(cc)) == 'Some class groovydoc for Foo'
  --------------------------------------
  
  === JSR308 improvements (work in progress)
  
  Groovy has been improving JSR-308 support over recent versions.
  As part of implementing the new grammar, additional support has been added.
  
  == JDK requirements
  
  
negative.code: | groovy.util
  | groovy.xml
  | For classes like `XmlParser` and `XmlSlurper`, you need to import `groovy.xml.XmlParser` and `groovy.xml.XmlSlurper` respectively to not
  get the deprecated versions. You will need to do this before Groovy 4. If you are using `groovy.xml.XmlUtil.serialize` on a
    `groovy.util.slurpersupport.GPathResult`, you will need to swap to using the deprecated methods in `groovy.util.XmlUtil` since
    `groovy.xml.XmlUtil` only handles the new classes.
  | org.codehaus.groovy.tools.xml.DomToGroovy
  