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 2020/08/21 23:42:53 UTC

[groovy] branch GROOVY_3_0_X updated (4dda037 -> 0d71a94)

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

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


    from 4dda037  GROOVY-9697: Bump asciidoctor to 3.2.0 (experimental pdf support - still fails rendering some code/images) (closes #1350)
     new d27e82c  Revert "GROOVY-9697: Bump asciidoctor to 3.2.0 (experimental pdf support - still fails rendering some code/images) (closes #1350)"
     new 0d71a94  Revert "GROOVY-9697: Bump asciidoctor to 3.2.0"

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 README.adoc                                        |  10 +-
 build.gradle                                       |   9 +-
 gradle/asciidoctor.gradle                          |  73 +--
 gradle/docs.gradle                                 |  16 +-
 src/spec/doc/core-closures.adoc                    |  88 ++--
 src/spec/doc/core-differences-java.adoc            |  32 +-
 src/spec/doc/core-domain-specific-languages.adoc   | 216 ++++-----
 src/spec/doc/core-gdk.adoc                         |  29 +-
 src/spec/doc/core-getting-started.adoc             |  10 +-
 src/spec/doc/core-metaprogramming.adoc             | 529 ++++++++++-----------
 src/spec/doc/core-object-orientation.adoc          | 156 +++---
 src/spec/doc/core-operators.adoc                   | 118 ++---
 src/spec/doc/core-program-structure.adoc           |  38 +-
 src/spec/doc/core-semantics.adoc                   | 384 +++++++--------
 src/spec/doc/core-syntax.adoc                      | 140 +++---
 src/spec/doc/core-testing-guide.adoc               |  46 +-
 .../doc/{fragment_traits.adoc => core-traits.adoc} | 138 +++---
 ...y.adoc => design-pattern-abstract-factory.adoc} |   8 +-
 ...rn-adapter.adoc => design-pattern-adapter.adoc} |  22 +-
 ...rn-bouncer.adoc => design-pattern-bouncer.adoc} |  12 +-
 ...=> design-pattern-chain-of-responsibility.adoc} |   2 +-
 ...omposite.adoc => design-pattern-composite.adoc} |   4 +-
 ...ecorator.adoc => design-pattern-decorator.adoc} |  36 +-
 ...egation.adoc => design-pattern-delegation.adoc} |  18 +-
 ...lyweight.adoc => design-pattern-flyweight.adoc} |   6 +-
 ...n-groovy.adoc => design-pattern-in-groovy.adoc} |  39 +-
 ...-iterator.adoc => design-pattern-iterator.adoc} |   6 +-
 ...e.adoc => design-pattern-loan-my-resource.adoc} |  10 +-
 ...object.adoc => design-pattern-null-object.adoc} |  12 +-
 ...ry.adoc => design-pattern-pimp-my-library.adoc} |   4 +-
 ...attern-proxy.adoc => design-pattern-proxy.adoc} |   6 +-
 ...ingleton.adoc => design-pattern-singleton.adoc} |  16 +-
 ...attern-state.adoc => design-pattern-state.adoc} |  26 +-
 ...-strategy.adoc => design-pattern-strategy.adoc} |   5 +-
 ...od.adoc => design-pattern-template-method.adoc} |   8 +-
 ...rn-visitor.adoc => design-pattern-visitor.adoc} |  14 +-
 src/spec/doc/guide-integrating.adoc                |  52 +-
 src/spec/doc/index.adoc                            |  67 ++-
 src/spec/doc/style-guide.adoc                      |   2 +-
 ...tensions.adoc => type-checking-extensions.adoc} |  80 ++--
 src/spec/doc/windows-nsis-installer.adoc           |   2 +-
 ...lections.adoc => working-with-collections.adoc} |  94 ++--
 ...t_working-with-io.adoc => working-with-io.adoc} |  50 +-
 src/spec/test/ClassTest.groovy                     |   2 +-
 ...{fragment_ant-builder.adoc => ant-builder.adoc} |   6 +-
 .../groovy-ant/src/spec/doc/groovy-ant-task.adoc   |   4 +-
 .../groovy-ant/src/spec/doc/groovyc-ant-task.adoc  |   2 +-
 ...t_integrating-bsf.adoc => integrating-bsf.adoc} |   4 +-
 ...types.adoc => working-with-datetime-types.adoc} |  36 +-
 ...types.adoc => working-with-dateutil-types.adoc} |   8 +-
 subprojects/groovy-jmx/src/spec/doc/jmx.adoc       |   2 +-
 ...ragment_json-builder.adoc => json-builder.adoc} |   0
 ...n-builder.adoc => streaming-jason-builder.adoc} |   0
 ...grating-jsr223.adoc => integrating-jsr223.adoc} |   0
 ...gment_swing-builder.adoc => swing-builder.adoc} |   0
 ...ate-engine.adoc => markup-template-engine.adoc} |   0
 .../src/spec/doc/template-engines.adoc             |  54 +--
 ...g-with-junit5.adoc => testing-with-junit5.adoc} |   2 +-
 ...{fragment_dom-builder.adoc => dom-builder.adoc} |   2 +-
 ...{fragment_sax-builder.adoc => sax-builder.adoc} |   0
 ...ragment_stax-builder.adoc => stax-builder.adoc} |   2 +-
 .../groovy-xml/src/spec/doc/xml-userguide.adoc     |   2 +-
 .../spec/test/groovy/yaml/YamlParserTest.groovy    |   1 +
 63 files changed, 1361 insertions(+), 1399 deletions(-)
 rename src/spec/doc/{fragment_traits.adoc => core-traits.adoc} (80%)
 rename src/spec/doc/{fragment_design-pattern-abstract-factory.adoc => design-pattern-abstract-factory.adoc} (90%)
 rename src/spec/doc/{fragment_design-pattern-adapter.adoc => design-pattern-adapter.adoc} (71%)
 rename src/spec/doc/{fragment_design-pattern-bouncer.adoc => design-pattern-bouncer.adoc} (77%)
 rename src/spec/doc/{fragment_design-pattern-chain-of-responsibility.adoc => design-pattern-chain-of-responsibility.adoc} (95%)
 rename src/spec/doc/{fragment_design-pattern-composite.adoc => design-pattern-composite.adoc} (74%)
 rename src/spec/doc/{fragment_design-pattern-decorator.adoc => design-pattern-decorator.adoc} (77%)
 rename src/spec/doc/{fragment_design-pattern-delegation.adoc => design-pattern-delegation.adoc} (72%)
 rename src/spec/doc/{fragment_design-pattern-flyweight.adoc => design-pattern-flyweight.adoc} (91%)
 rename src/spec/doc/{design-patterns-in-groovy.adoc => design-pattern-in-groovy.adoc} (61%)
 rename src/spec/doc/{fragment_design-pattern-iterator.adoc => design-pattern-iterator.adoc} (78%)
 rename src/spec/doc/{fragment_design-pattern-loan-my-resource.adoc => design-pattern-loan-my-resource.adoc} (84%)
 rename src/spec/doc/{fragment_design-pattern-null-object.adoc => design-pattern-null-object.adoc} (84%)
 rename src/spec/doc/{fragment_design-pattern-pimp-my-library.adoc => design-pattern-pimp-my-library.adoc} (92%)
 rename src/spec/doc/{fragment_design-pattern-proxy.adoc => design-pattern-proxy.adoc} (65%)
 rename src/spec/doc/{fragment_design-pattern-singleton.adoc => design-pattern-singleton.adoc} (90%)
 rename src/spec/doc/{fragment_design-pattern-state.adoc => design-pattern-state.adoc} (66%)
 rename src/spec/doc/{fragment_design-pattern-strategy.adoc => design-pattern-strategy.adoc} (91%)
 rename src/spec/doc/{fragment_design-pattern-template-method.adoc => design-pattern-template-method.adoc} (84%)
 rename src/spec/doc/{fragment_design-pattern-visitor.adoc => design-pattern-visitor.adoc} (91%)
 rename src/spec/doc/{fragment_type-checking-extensions.adoc => type-checking-extensions.adoc} (91%)
 rename src/spec/doc/{fragment_working-with-collections.adoc => working-with-collections.adoc} (77%)
 rename src/spec/doc/{fragment_working-with-io.adoc => working-with-io.adoc} (79%)
 rename subprojects/groovy-ant/src/spec/doc/{fragment_ant-builder.adoc => ant-builder.adoc} (93%)
 rename subprojects/groovy-bsf/src/spec/doc/{fragment_integrating-bsf.adoc => integrating-bsf.adoc} (95%)
 rename subprojects/groovy-datetime/src/spec/doc/{fragment_working-with-datetime-types.adoc => working-with-datetime-types.adoc} (83%)
 rename subprojects/groovy-dateutil/src/spec/doc/{fragment_working-with-dateutil-types.adoc => working-with-dateutil-types.adoc} (78%)
 rename subprojects/groovy-json/src/spec/doc/{fragment_json-builder.adoc => json-builder.adoc} (100%)
 rename subprojects/groovy-json/src/spec/doc/{fragment_streaming-jason-builder.adoc => streaming-jason-builder.adoc} (100%)
 rename subprojects/groovy-jsr223/src/spec/doc/{fragment_integrating-jsr223.adoc => integrating-jsr223.adoc} (100%)
 rename subprojects/groovy-swing/src/spec/doc/{fragment_swing-builder.adoc => swing-builder.adoc} (100%)
 rename subprojects/groovy-templates/src/spec/doc/{fragment_markup-template-engine.adoc => markup-template-engine.adoc} (100%)
 rename subprojects/groovy-test-junit5/src/spec/doc/{fragment_testing-with-junit5.adoc => testing-with-junit5.adoc} (97%)
 rename subprojects/groovy-xml/src/spec/doc/{fragment_dom-builder.adoc => dom-builder.adoc} (94%)
 rename subprojects/groovy-xml/src/spec/doc/{fragment_sax-builder.adoc => sax-builder.adoc} (100%)
 rename subprojects/groovy-xml/src/spec/doc/{fragment_stax-builder.adoc => stax-builder.adoc} (92%)


[groovy] 01/02: Revert "GROOVY-9697: Bump asciidoctor to 3.2.0 (experimental pdf support - still fails rendering some code/images) (closes #1350)"

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit d27e82c682c6dec0ea244fa74d7019b115f58925
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sat Aug 22 09:41:40 2020 +1000

    Revert "GROOVY-9697: Bump asciidoctor to 3.2.0 (experimental pdf support - still fails rendering some code/images) (closes #1350)"
    
    This reverts commit 4dda037b09a4e1d86023020239f37aae97bc9b64. We need to fix up classpath issues first.
---
 build.gradle              |  1 -
 gradle/asciidoctor.gradle |  6 +++---
 gradle/docs.gradle        | 14 +-------------
 3 files changed, 4 insertions(+), 17 deletions(-)

diff --git a/build.gradle b/build.gradle
index ab207fb..7969a5e 100644
--- a/build.gradle
+++ b/build.gradle
@@ -45,7 +45,6 @@ buildscript {
 }
 
 plugins {
-    id 'org.asciidoctor.jvm.pdf' version '3.2.0'
     id 'me.champeau.buildscan-recipes' version '0.2.3'
     id 'com.github.spotbugs' version '4.5.0'
     id 'com.github.ben-manes.versions' version '0.29.0'
diff --git a/gradle/asciidoctor.gradle b/gradle/asciidoctor.gradle
index 623d841..4e45715 100644
--- a/gradle/asciidoctor.gradle
+++ b/gradle/asciidoctor.gradle
@@ -76,10 +76,10 @@ asciidoctorj {
             }
         }
     }
-    modules {
+//    modules {
 //        diagram.version('2.0.2')
-        pdf.version('1.5.3')
-    }
+//        pdf.version('1.5.3')
+//    }
 }
 
 // skip the asciidoctor task if there's no directory with asciidoc files
diff --git a/gradle/docs.gradle b/gradle/docs.gradle
index e9ff503..a39136e 100644
--- a/gradle/docs.gradle
+++ b/gradle/docs.gradle
@@ -17,7 +17,7 @@
  *  under the License.
  */
 
-task doc(dependsOn: ['javadocAll', 'groovydocAll', 'docGDK', 'asciidocAll', 'asciidoctorPdf']) {
+task doc(dependsOn: ['javadocAll', 'groovydocAll', 'docGDK', 'asciidocAll']) {
     ext.footer = 'Copyright &copy; 2003-2020 The Apache Software Foundation. All rights reserved.'
     ext.title = "Groovy ${groovyVersion}"
 }
@@ -30,18 +30,6 @@ task asciidocAll(type: Copy) {
     into "$buildDir/asciidocAll/html5"
 }
 
-asciidoctorPdf {
-    baseDirIsRootProjectDir() // needed for asciidocAll
-    logDocuments = true
-    sourceDir = project.file('src/spec/doc')
-    sources {
-        include 'index.adoc'
-    }
-    outputDir = "$buildDir/asciidoc/pdf"
-    attributes 'rootProjectDir': rootProject.projectDir,
-            specfolder: 'src/spec/doc'
-}
-
 def javadocSpec = {
     maxMemory = javaDoc_mx
     project.configure(options) {


[groovy] 02/02: Revert "GROOVY-9697: Bump asciidoctor to 3.2.0"

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 0d71a940b7e4a17dbee8f3849c009ed19b1284d4
Author: Paul King <pa...@asert.com.au>
AuthorDate: Sat Aug 22 09:42:12 2020 +1000

    Revert "GROOVY-9697: Bump asciidoctor to 3.2.0"
    
    This reverts commit 97a12501be10cb905ae263c6c739fc0efd3d7ef2.
---
 README.adoc                                        |  10 +-
 build.gradle                                       |   8 +-
 gradle/asciidoctor.gradle                          |  73 +--
 gradle/docs.gradle                                 |   2 +-
 src/spec/doc/core-closures.adoc                    |  88 ++--
 src/spec/doc/core-differences-java.adoc            |  32 +-
 src/spec/doc/core-domain-specific-languages.adoc   | 216 ++++-----
 src/spec/doc/core-gdk.adoc                         |  29 +-
 src/spec/doc/core-getting-started.adoc             |  10 +-
 src/spec/doc/core-metaprogramming.adoc             | 529 ++++++++++-----------
 src/spec/doc/core-object-orientation.adoc          | 156 +++---
 src/spec/doc/core-operators.adoc                   | 118 ++---
 src/spec/doc/core-program-structure.adoc           |  38 +-
 src/spec/doc/core-semantics.adoc                   | 384 +++++++--------
 src/spec/doc/core-syntax.adoc                      | 140 +++---
 src/spec/doc/core-testing-guide.adoc               |  46 +-
 .../doc/{fragment_traits.adoc => core-traits.adoc} | 138 +++---
 ...y.adoc => design-pattern-abstract-factory.adoc} |   8 +-
 ...rn-adapter.adoc => design-pattern-adapter.adoc} |  22 +-
 ...rn-bouncer.adoc => design-pattern-bouncer.adoc} |  12 +-
 ...=> design-pattern-chain-of-responsibility.adoc} |   2 +-
 ...omposite.adoc => design-pattern-composite.adoc} |   4 +-
 ...ecorator.adoc => design-pattern-decorator.adoc} |  36 +-
 ...egation.adoc => design-pattern-delegation.adoc} |  18 +-
 ...lyweight.adoc => design-pattern-flyweight.adoc} |   6 +-
 ...n-groovy.adoc => design-pattern-in-groovy.adoc} |  39 +-
 ...-iterator.adoc => design-pattern-iterator.adoc} |   6 +-
 ...e.adoc => design-pattern-loan-my-resource.adoc} |  10 +-
 ...object.adoc => design-pattern-null-object.adoc} |  12 +-
 ...ry.adoc => design-pattern-pimp-my-library.adoc} |   4 +-
 ...attern-proxy.adoc => design-pattern-proxy.adoc} |   6 +-
 ...ingleton.adoc => design-pattern-singleton.adoc} |  16 +-
 ...attern-state.adoc => design-pattern-state.adoc} |  26 +-
 ...-strategy.adoc => design-pattern-strategy.adoc} |   5 +-
 ...od.adoc => design-pattern-template-method.adoc} |   8 +-
 ...rn-visitor.adoc => design-pattern-visitor.adoc} |  14 +-
 src/spec/doc/guide-integrating.adoc                |  52 +-
 src/spec/doc/index.adoc                            |  67 ++-
 src/spec/doc/style-guide.adoc                      |   2 +-
 ...tensions.adoc => type-checking-extensions.adoc} |  80 ++--
 src/spec/doc/windows-nsis-installer.adoc           |   2 +-
 ...lections.adoc => working-with-collections.adoc} |  94 ++--
 ...t_working-with-io.adoc => working-with-io.adoc} |  50 +-
 src/spec/test/ClassTest.groovy                     |   2 +-
 ...{fragment_ant-builder.adoc => ant-builder.adoc} |   6 +-
 .../groovy-ant/src/spec/doc/groovy-ant-task.adoc   |   4 +-
 .../groovy-ant/src/spec/doc/groovyc-ant-task.adoc  |   2 +-
 ...t_integrating-bsf.adoc => integrating-bsf.adoc} |   4 +-
 ...types.adoc => working-with-datetime-types.adoc} |  36 +-
 ...types.adoc => working-with-dateutil-types.adoc} |   8 +-
 subprojects/groovy-jmx/src/spec/doc/jmx.adoc       |   2 +-
 ...ragment_json-builder.adoc => json-builder.adoc} |   0
 ...n-builder.adoc => streaming-jason-builder.adoc} |   0
 ...grating-jsr223.adoc => integrating-jsr223.adoc} |   0
 ...gment_swing-builder.adoc => swing-builder.adoc} |   0
 ...ate-engine.adoc => markup-template-engine.adoc} |   0
 .../src/spec/doc/template-engines.adoc             |  54 +--
 ...g-with-junit5.adoc => testing-with-junit5.adoc} |   2 +-
 ...{fragment_dom-builder.adoc => dom-builder.adoc} |   2 +-
 ...{fragment_sax-builder.adoc => sax-builder.adoc} |   0
 ...ragment_stax-builder.adoc => stax-builder.adoc} |   2 +-
 .../groovy-xml/src/spec/doc/xml-userguide.adoc     |   2 +-
 .../spec/test/groovy/yaml/YamlParserTest.groovy    |   1 +
 63 files changed, 1360 insertions(+), 1385 deletions(-)

diff --git a/README.adoc b/README.adoc
index 4ddf17e..ecca2aa 100644
--- a/README.adoc
+++ b/README.adoc
@@ -22,12 +22,12 @@
 = Apache Groovy
 The Groovy development team
 :revdate: 24-02-2014
-:build-icon: https://ci.groovy-lang.org:8111/app/rest/builds/buildType:(id:Groovy_Jdk7Build)/statusIcon
+:build-icon: http://ci.groovy-lang.org:8111/app/rest/builds/buildType:(id:Groovy_Jdk7Build)/statusIcon
 :travis-build-icon: https://travis-ci.org/apache/groovy.svg?branch=master
 :sonarcloud-icon: https://sonarcloud.io/api/project_badges/measure?project=apache_groovy&metric=sqale_rating
 :noheader:
 :groovy-www: https://groovy-lang.org/
-:groovy-ci: https://ci.groovy-lang.org?guest=1
+:groovy-ci: http://ci.groovy-lang.org?guest=1
 :travis-ci: https://travis-ci.org/apache/groovy
 :sonarcloud: https://sonarcloud.io/dashboard?id=apache_groovy
 :jdk: https://www.oracle.com/technetwork/java/javase/downloads
@@ -36,7 +36,7 @@ The Groovy development team
 :bintray-watch-image: https://www.bintray.com/docs/images/bintray_badge_color.png
 :bintray-watch-link: https://bintray.com/groovy/maven/groovy/view?source=watch
 :apache-license-icon: https://img.shields.io/badge/license-APL2-blue.svg
-:apache-license-link: https://www.apache.org/licenses/LICENSE-2.0.txt
+:apache-license-link: http://www.apache.org/licenses/LICENSE-2.0.txt
 :apache-groovy-twitter-icon: https://img.shields.io/twitter/follow/ApacheGroovy.svg?style=social
 :apache-groovy-twitter-link: https://twitter.com/intent/follow?screen_name=ApacheGroovy
 :jdk-icon: https://img.shields.io/badge/java-8+-4c7e9f.svg
@@ -98,7 +98,7 @@ Simply `git clone` the repo (or the repo you forked via the github website) and
 Alternatively, you can download the source distribution and unpack it.
 
 If obtaining the source from the source distribution and you intend to build from source,
-you also need to https://gradle.org/downloads/[download] and install https://gradle.org/[Gradle] and
+you also need to https://gradle.org/downloads/[download] and install http://gradle.org/[Gradle] and
 use it to execute one bootstrap step.
 
 ==== Bootstrapping Gradle
@@ -188,7 +188,7 @@ Please note that the following Gradle tasks generate both indy and non indy vari
 
 == Continuous Integration Server
 
-The official CI server runs {groovy-ci}[here] and is sponsored by https://www.jetbrains.com[JetBrains].
+The official CI server runs {groovy-ci}[here] and is sponsored by http://www.jetbrains.com[JetBrains].
 
 == Java Profiler
 
diff --git a/build.gradle b/build.gradle
index 7969a5e..51d232d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -36,7 +36,7 @@ buildscript {
 
     dependencies {
         // using the old "classpath" style of plugins because the new one doesn't play well with multi-modules
-        classpath "org.asciidoctor:asciidoctor-gradle-jvm:3.2.0"
+        classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.8'
         classpath "org.jfrog.buildinfo:build-info-extractor-gradle:3.0.3"
         //classpath 'nl.javadude.gradle.plugins:license-gradle-plugin:0.11.0'
         classpath "org.nosphere.apache:creadur-rat-gradle:0.7.0"
@@ -52,10 +52,6 @@ plugins {
     id 'org.sonarqube' version '2.8'
 }
 
-//configurations {
-//    asciidoctorExtensions
-//}
-
 buildScanRecipes {
     recipe 'git-commit', baseUrl: 'https://github.com/apache/groovy/tree'
     recipe 'teamcity', baseUrl: 'https://ci.groovy-lang.org', guest: 'true'
@@ -108,7 +104,7 @@ allprojects {
     apply from: "${rootProject.projectDir}/gradle/indy.gradle"
     apply from: "${rootProject.projectDir}/gradle/asciidoctor.gradle"
 
-    tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
+    tasks.withType(org.asciidoctor.gradle.AsciidoctorTask) {
         outputs.cacheIf { true }
     }
 }
diff --git a/gradle/asciidoctor.gradle b/gradle/asciidoctor.gradle
index 4e45715..0fad8aa 100644
--- a/gradle/asciidoctor.gradle
+++ b/gradle/asciidoctor.gradle
@@ -16,25 +16,15 @@
  *  specific language governing permissions and limitations
  *  under the License.
  */
-apply plugin: 'org.asciidoctor.jvm.convert'
+apply plugin: 'org.asciidoctor.gradle.asciidoctor'
 
 asciidoctor {
-    baseDirIsRootProjectDir() // needed for asciidocAll
     def (full, major, minor, patch, flavor) = (groovyVersion =~ /(\d+)\.(\d++)\.(\d+)(?:-(.+))?/)[0]
     logDocuments = true
     sourceDir = project.file('src/spec/doc')
-    sources {
-        include '*.adoc'
-        exclude 'fragment_*.adoc'
-    }
-    outputDir = "$buildDir/asciidoc/html5"
-    resources {
-        from( "${rootProject.projectDir}/src/spec/doc/assets" ) {
-            include 'css/style.css'
-        }
-        into 'assets'
-    }
-    attributes 'rootProjectDir': rootProject.projectDir,
+
+    attributes([
+            'rootProjectDir': rootProject.projectDir,
             'source-highlighter': 'prettify',
             groovyversion: groovyVersion,
             'groovy-major-version': major,
@@ -53,33 +43,41 @@ asciidoctor {
             toclevels: 10,
             numbered: '',
             sectanchors: ''
-}
+    ])
+
+    extensions {
 
-asciidoctorj {
-    jrubyVersion = '1.5.8'
-    version = '2.4.0'
-    def vers = groovyVersion
-    docExtensions {
         def baseUrls = [
-                jdk: 'https://docs.oracle.com/en/java/javase/11/docs/api/index.html',
-                gjdk: "https://docs.groovy-lang.org/${vers}/html/groovy-jdk/index.html",
-                gapi: "https://docs.groovy-lang.org/${vers}/html/gapi/index.html",
-                gapid:  "https://docs.groovy-lang.org/${vers}/html/gapi/",
+                jdk: "https://docs.oracle.com/javase/8/docs/api/index.html",
+                gjdk: "https://docs.groovy-lang.org/${version}/html/groovy-jdk/index.html",
+                gapi: "https://docs.groovy-lang.org/${version}/html/gapi/index.html",
+                gapid:  "https://docs.groovy-lang.org/${version}/html/gapi/",
         ]
+
         baseUrls.each { macroName, baseURL ->
-            inline_macro(name: macroName) {
+            inlinemacro(name: macroName) {
                 parent, target, attributes ->
                     def (className, anchor) = target.split('#') as List
-                    def base = className == 'index' ?
-                            baseURL : baseURL + '?' + className.replace('.', '/') + '.html' + (anchor ? '#' + anchor : '')
-                    createPhraseNode(parent, 'anchor', attributes.text?:target, attributes, [type: ':link', target: base])
+                    options = [
+                            "type"  : ":link",
+                            "target": calculateDocUrl(baseURL, className, anchor),
+                    ]
+
+                    createInline(parent, "anchor", attributes.text?:target, attributes, options).render()
             }
         }
+
+        inlinemacro('gapid') { parent, target, attributes ->
+            def (className, anchor) = target.split('#') as List
+
+            def partialUrl = { -> className.replace('.', '/') + '.html' + (anchor ? '#' + anchor.replace(',',', ') : '')}
+            options = [
+                    "type": ":link",
+                    "target": "${baseUrls['gapid']}${partialUrl()}",
+            ]
+            createInline(parent, "anchor", attributes.text?:target, attributes, options).render()
+        }
     }
-//    modules {
-//        diagram.version('2.0.2')
-//        pdf.version('1.5.3')
-//    }
 }
 
 // skip the asciidoctor task if there's no directory with asciidoc files
@@ -87,7 +85,7 @@ asciidoctor.onlyIf { project.file('src/spec/doc').exists() }
 
 task asciidoctorAssets(type:Copy) {
     from project.fileTree('src/spec/doc/assets')
-    into "${asciidoctor.outputDir}/assets"
+    into "${asciidoctor.outputDir}/html5/assets"
 }
 asciidoctor.dependsOn asciidoctorAssets
 
@@ -116,7 +114,7 @@ def htmlOutputSanityCheck = { file, text, errors ->
         if (line =~ /<code class=".+?"><\/code>/) {
             localErrors << "contains empty code block, probably incorrect import of a tag."
         }
-        if (line =~ /(gapi|jdk|gjdk):(\S.+?)/) {
+        if (line =~ /(gapi|jdk|gjdk):(.+?)/) {
             localErrors << "line $i starting with asciidoctor raw markup:\n$line"
         }
     }
@@ -140,6 +138,7 @@ asciidoctor {
     }
 
     doLast {
+
         def scripts = '''<link rel="stylesheet" href="assets/css/view-example.css">
 <script src='assets/js/jquery-min-2.1.1.js'></script>
 <script src='assets/js/view-example.js'></script>'''
@@ -156,3 +155,9 @@ asciidoctor {
         }
     }
 }
+
+String calculateDocUrl(String baseUrl, String className, String anchor) {
+    if (className == "index") return baseUrl
+
+    return baseUrl + "?" + className.replace('.', '/') + '.html' + (anchor ? '#' + anchor : '')
+}
\ No newline at end of file
diff --git a/gradle/docs.gradle b/gradle/docs.gradle
index a39136e..21973f1 100644
--- a/gradle/docs.gradle
+++ b/gradle/docs.gradle
@@ -27,7 +27,7 @@ task asciidocAll(type: Copy) {
         dependsOn asciidoctor
         from asciidoctor.outputDir
     }
-    into "$buildDir/asciidocAll/html5"
+    into "$buildDir/asciidocAll"
 }
 
 def javadocSpec = {
diff --git a/src/spec/doc/core-closures.adoc b/src/spec/doc/core-closures.adoc
index d2998bf..9ea914e 100644
--- a/src/spec/doc/core-closures.adoc
+++ b/src/spec/doc/core-closures.adoc
@@ -21,7 +21,7 @@
 
 = Closures
 
-:lambdas: https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html[lambda expressions in Java 8]
+:lambdas: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html[lambda expressions in Java 8]
 
 This chapter covers Groovy Closures. A closure in Groovy is an open, anonymous, block of code that can take arguments,
 return a value and be assigned to a variable. A closure may reference variables declared in its surrounding scope. In
@@ -52,19 +52,19 @@ Some examples of valid closure definitions:
 
 [source,groovy]
 -----------------------------------------------------------
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_1,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_1,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_1bis,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_1bis,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_2,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_2,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_3,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_3,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_4,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_4,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_5,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_5,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_syntax_6,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_syntax_6,indent=0]
 -----------------------------------------------------------
 <1> A closure referencing a variable named `item`
 <2> It is possible to explicitly separate closure parameters from code by adding an arrow (`+->+`)
@@ -82,7 +82,7 @@ other variable, despite being a block of code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_is_an_instance_of_Closure,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_is_an_instance_of_Closure,indent=0]
 ----
 <1> You can assign a closure to a variable, and it is an instance of `groovy.lang.Closure`
 <2> If not using `def` or `var`, use `groovy.lang.Closure` as the type
@@ -95,7 +95,7 @@ no argument like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_call_1,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_call_1,indent=0]
 ----
 
 Then the code inside the closure will only be executed when you _call_ the closure, which can be done by using the
@@ -103,21 +103,21 @@ variable as if it was a regular method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_call_1_direct,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_call_1_direct,indent=0]
 ----
 
 Alternatively, you can be explicit and use the `call` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_call_1_explicit,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_call_1_explicit,indent=0]
 ----
 
 The principle is the same if the closure accepts arguments:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_call_2,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_call_2,indent=0]
 ----
 <1> define a closure which accepts an `int` as a parameter
 <2> it can be called directly
@@ -143,7 +143,7 @@ Parameters are separated with commas:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_param_declaration,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_param_declaration,indent=0]
 ----
 
 [[implicit-it]]
@@ -154,14 +154,14 @@ parameter, named `it`. This means that this code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=implicit_it,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=implicit_it,indent=0]
 ----
 
 is stricly equivalent to this one:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=implicit_it_equiv,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=implicit_it_equiv,indent=0]
 ----
 
 If you want to declare a closure which accepts no argument and must be restricted to calls without arguments,
@@ -169,9 +169,9 @@ then you *must* declare it with an explicit empty argument list:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_no_arg_def,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_no_arg_def,indent=0]
 
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_no_arg_fail,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_no_arg_fail,indent=0]
 ----
 
 === Varargs
@@ -182,7 +182,7 @@ examples:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_vargs,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_vargs,indent=0]
 ----
 <1> A closure accepting a variable number of strings as first parameter
 <2> It may be called using any number of arguments *without* having to explicitly wrap them into an array
@@ -217,7 +217,7 @@ using an explicit `this`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_this,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_this,indent=0]
 ----
 <1> a closure is defined inside the `Enclosing` class, and returns `getThisObject`
 <2> calling the closure will return the instance of `Enclosing` where the closure is defined
@@ -232,7 +232,7 @@ It is of course possible to call methods from the enclosing class this way:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_this_call,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_this_call,indent=0]
 ----
 <1> the closure calls `toString` on `this`, which will actually call the `toString` method on the enclosing object,
 that is to say the `Person` instance
@@ -244,7 +244,7 @@ it will return the direct enclosing object, be it a closure or a class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_owner,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_owner,indent=0]
 ----
 <1> a closure is defined inside the `Enclosing` class, and returns `getOwner`
 <2> calling the closure will return the instance of `Enclosing` where the closure is defined
@@ -258,13 +258,13 @@ include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_owner,indent=
 ==== Delegate of a closure
 
 The delegate of a closure can be accessed by using the `delegate` property or calling the `getDelegate` method. It is a
-powerful concept for building domain specific languages in Groovy. While <<closure-this,this>> and <<closure-owner,owner>>
+powerful concept for building domain specific languages in Groovy. While <<this,closure-this>> and <<owner,closure-owner>>
 refer to the lexical scope of a closure, the delegate is a user defined object that a closure will use. By default, the
 delegate is set to `owner`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=delegate_is_owner,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=delegate_is_owner,indent=0]
 ----
 <1> you can get the delegate of a closure calling the `getDelegate` method
 <2> or using the `delegate` property
@@ -278,28 +278,28 @@ subclasses of each other but both define a property called `name`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=change_delegate_classes,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=change_delegate_classes,indent=0]
 ----
 
 Then let's define a closure which fetches the `name` property on the delegate:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=change_delegate_closure,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=change_delegate_closure,indent=0]
 ----
 
 Then by changing the delegate of the closure, you can see that the target object will change:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=change_delegate_asserts,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=change_delegate_asserts,indent=0]
 ----
 
 At this point, the behavior is not different from having a `target` variable defined in the lexical scope of the closure:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=delegate_alernative,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=delegate_alernative,indent=0]
 ----
 
 However, there are major differences:
@@ -315,7 +315,7 @@ is involved:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=delegation_strategy_intro,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=delegation_strategy_intro,indent=0]
 ----
 <1> `name` is not referencing a variable in the lexical scope of the closure
 <2> we can change the delegate of the closure to be an instance of `Person`
@@ -339,7 +339,7 @@ Let's illustrate the default "owner first" strategy with this code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_owner_first,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_owner_first,indent=0]
 ----
 <1> for the illustration, we define a closure member which references "name"
 <2> both the `Person` and the `Thing` class define a `name` property
@@ -351,7 +351,7 @@ However, it is possible to change the resolution strategy of the closure:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_delegate_first,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_delegate_first,indent=0]
 ----
 
 By changing the `resolveStrategy`, we are modifying the way Groovy will resolve the "implicit this" references: in this
@@ -363,7 +363,7 @@ of the delegate (resp. owner) does *not* have such a method or property:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=delegate_only,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=delegate_only,indent=0]
 ----
 
 In this example, we define two classes which both have a `name` property but only the `Person` class declares an `age`.
@@ -382,14 +382,14 @@ Take the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=gstring_eager_intro,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=gstring_eager_intro,indent=0]
 ----
 
 The code behaves as you would expect, but what happens if you add:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=gstring_eager_outro,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=gstring_eager_outro,indent=0]
 ----
 
 You will see that the assert fails! There are two reasons for this:
@@ -411,14 +411,14 @@ alternate syntax `${-> x}` like in the fixed example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=gstring_lazy,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=gstring_lazy,indent=0]
 ----
 
 And let's illustrate how it differs from mutation with this code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=gstring_mutation,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=gstring_mutation,indent=0]
 ----
 <1> the `Person` class has a `toString` method returning the `name` property
 <2> we create a first `Person` named _Sam_
@@ -436,7 +436,7 @@ declaring an empty argument list:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=gstring_no_mutation,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=gstring_no_mutation,indent=0]
 ----
 
 == Closure coercion
@@ -461,7 +461,7 @@ Left currying is the fact of setting the left-most parameter of a closure, like
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=left_curry,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=left_curry,indent=0]
 ----
 <1> the `nCopies` closure defines two parameters
 <2> `curry` will set the first parameter to `2`, creating a new closure (function) which accepts a single `String`
@@ -474,7 +474,7 @@ Similarily to left currying, it is possible to set the right-most parameter of a
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=right_curry,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=right_curry,indent=0]
 ----
 <1> the `nCopies` closure defines two parameters
 <2> `rcurry` will set the last parameter to `bla`, creating a new closure (function) which accepts a single `int`
@@ -487,7 +487,7 @@ In case a closure accepts more than 2 parameters, it is possible to set an arbit
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=ncurry,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=ncurry,indent=0]
 ----
 <1> the `volume` function defines 3 parameters
 <2> `ncurry` will set the second parameter (index = 1) to `2d`, creating a new volume function which accepts length and height
@@ -503,7 +503,7 @@ typical example is the Fibonacci suite. A naive implementation may look like thi
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=naive_fib,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=naive_fib,indent=0]
 ----
 
 It is a naive implementation because 'fib' is often called recursively with the same arguments, leading to an exponential
@@ -517,7 +517,7 @@ be cached. This naive implementation can be "fixed" by caching the result of cal
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=memoized_fib,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=memoized_fib,indent=0]
 ----
 
 WARNING: The cache works *using the actual values of the arguments*. This means that you should be very careful if you use
@@ -538,7 +538,7 @@ composing two or more functions (chaining calls), as illustrated in this example
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=closure_composition,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=closure_composition,indent=0]
 ----
 
 === Trampoline
@@ -558,7 +558,7 @@ Here’s an example of the use of `trampoline()` to implement the factorial func
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClosuresSpecTest.groovy[tags=trampoline,indent=0]
+include::{projectdir}/src/spec/test/ClosuresSpecTest.groovy[tags=trampoline,indent=0]
 ----
 
 === Method pointers
diff --git a/src/spec/doc/core-differences-java.adoc b/src/spec/doc/core-differences-java.adoc
index 5630568..4d5cb18 100644
--- a/src/spec/doc/core-differences-java.adoc
+++ b/src/spec/doc/core-differences-java.adoc
@@ -52,21 +52,21 @@ The following code, written as Java code, can be compiled in both Java and Groov
 
 [source,java]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=multimethods,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=multimethods,indent=0]
 ----
 
 In Java, you would have:
 
 [source,java]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=multimethods_java,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=multimethods_java,indent=0]
 ----
 
 Whereas in Groovy:
 
 [source,java]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=multimethods_groovy,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=multimethods_groovy,indent=0]
 ----
 
 That is because Java will use the static information type, which is that `o` is declared as an `Object`, whereas
@@ -79,7 +79,7 @@ In Java, array initializers take either of these two forms:
 
 [source,java]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=arraycreate_fail,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=arraycreate_fail,indent=0]
 ----
 
 In Groovy, the `{ ... }` block is reserved for closures.
@@ -88,14 +88,14 @@ You instead borrow Groovy's literal list notation like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=arraycreate_success,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=arraycreate_success,indent=0]
 ----
 
 For Groovy 3+, you can optionally use the Java's array initializer long syntax:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=arraycreate3_success,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=arraycreate3_success,indent=0]
 ----
 
 == Package scope visibility
@@ -104,7 +104,7 @@ In Groovy, omitting a modifier on a field doesn't result in a package-private fi
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=packageprivate_property,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=packageprivate_property,indent=0]
 ----
 
 Instead, it is used to create a _property_, that is to say a _private field_, an associated _getter_ and an associated
@@ -114,7 +114,7 @@ It is possible to create a package-private field by annotating it with `@Package
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=packageprivate_field,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=packageprivate_field,indent=0]
 ----
 
 == ARM blocks
@@ -171,7 +171,7 @@ Here's an example of static inner class:
 
 [source,groovy]
 ---------------------
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=innerclass_1,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=innerclass_1,indent=0]
 ---------------------
 
 The usage of static inner classes is the best supported one. If you
@@ -181,7 +181,7 @@ absolutely need an inner class, you should make it a static one.
 
 [source,groovy]
 ---------------------
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=innerclass_2,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=innerclass_2,indent=0]
 ---------------------
 
 === Creating Instances of Non-Static Inner Classes
@@ -190,14 +190,14 @@ In Java you can do this:
 
 [source,java]
 ----------------------------------
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=innerclass_3_java,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=innerclass_3_java,indent=0]
 ----------------------------------
 
 Before 3.0.0, Groovy doesn't support the `y.new X()` syntax. Instead, you have to write `new X(y)`, like in the code below:
 
 [source,groovy]
 ----------------------------------
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=innerclass_3,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=innerclass_3,indent=0]
 ----------------------------------
 
 [WARNING]
@@ -248,7 +248,7 @@ Singly-quoted literals in Groovy are used for `String`, and double-quoted result
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=type_depends_on_quoting_AND_whether_we_actually_interpolate,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=type_depends_on_quoting_AND_whether_we_actually_interpolate,indent=0]
 ----
 
 Groovy will automatically cast a single-character `String` to `char` only when assigning to
@@ -257,7 +257,7 @@ to either cast explicitly or make sure the value has been cast in advance.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=single_char_strings_are_autocasted,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=single_char_strings_are_autocasted,indent=0]
 ----
 
 Groovy supports two styles of casting and in the case of casting to `char` there
@@ -267,7 +267,7 @@ with exception.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DifferencesFromJavaTest.groovy[tags=chars_c_vs_groovy_cast,indent=0]
+include::{projectdir}/src/spec/test/DifferencesFromJavaTest.groovy[tags=chars_c_vs_groovy_cast,indent=0]
 ----
 
 == Primitives and wrappers
@@ -278,7 +278,7 @@ Here's an example using `int`
 
 [source,groovy]
 ----
-include::{includedir}/../test/PrimitiveTest.groovy[tags=widening_vs_boxing,indent=0]
+include::{projectdir}/src/spec/test/PrimitiveTest.groovy[tags=widening_vs_boxing,indent=0]
 ----
 <1> This is the method that Java would call, since widening has precedence over unboxing.
 <2> This is the method Groovy actually calls, since all primitive references use their wrapper class.
diff --git a/src/spec/doc/core-domain-specific-languages.adoc b/src/spec/doc/core-domain-specific-languages.adoc
index ab71d50..e2f74af 100644
--- a/src/spec/doc/core-domain-specific-languages.adoc
+++ b/src/spec/doc/core-domain-specific-languages.adoc
@@ -33,15 +33,15 @@ supported by this new syntax:
 
 [source,groovy]
 ---------------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_1,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_1,indent=0]
 
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_2,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_2,indent=0]
 
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_3,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_3,indent=0]
 
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_4,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_4,indent=0]
 
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_5,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_5,indent=0]
 ---------------------------------------------------------------------------------------------------------------
 
 It is also possible to use methods in the chain which take no arguments,
@@ -49,7 +49,7 @@ but in that case, the parentheses are needed:
 
 [source,groovy]
 -------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_6,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_6,indent=0]
 -------------------------------------------------------------------------------------------------
 
 If your command chain contains an odd number of elements, the chain will
@@ -58,7 +58,7 @@ access:
 
 [source,groovy]
 -------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_7,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_7,indent=0]
 -------------------------------------------------------------------------------------
 
 This command chain approach opens up interesting possibilities in terms of the much wider range of DSLs which
@@ -69,7 +69,7 @@ that you can use, but to illustrate creating such a DSL, we will show a couple o
 
 [source,groovy]
 ------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl1,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl1,indent=0]
 ------------------------------------------------------------------------------------------------------
 
 As a second example, consider how you might write a DSL for simplifying
@@ -82,8 +82,8 @@ box:
 
 [source,groovy]
 ----------------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl2,indent=0]
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl2,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
 ----------------------------------------------------------------------------------------------------------------
 
 It reads fairly well for a Java developer but if that is not your target
@@ -94,21 +94,21 @@ helper method:
 
 [source,groovy]
 ------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl3,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl3,indent=0]
 ------------------------------------------------------------------------------------------------------
 
 now instead of this line from our original example:
 
 [source,groovy]
 ----------------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl2_assert,indent=0]
 ----------------------------------------------------------------------------------------------------------------
 
 we can write this:
 
 [source,groovy]
 -----------------------------------------------------
-include::{includedir}/../test/CommandChainsTest.groovy[tags=commandchain_impl3_assert,indent=0]
+include::{projectdir}/src/spec/test/CommandChainsTest.groovy[tags=commandchain_impl3_assert,indent=0]
 -----------------------------------------------------
 
 
@@ -158,7 +158,7 @@ Groovy scripts are always compiled to classes. For example, a script as simple a
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=simple_script,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=simple_script,indent=0]
 ----
 
 is compiled to a class extending the abstract gapi:groovy.lang.Script[] class. This class contains a single abstract
@@ -168,7 +168,7 @@ with your application through the `Binding` object, as illustrated in this examp
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=integ_binding,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=integ_binding,indent=0]
 ----
 <1> a binding is used to share data between the script and the calling class
 <2> a `GroovyShell` can be used with this binding
@@ -182,14 +182,14 @@ has to extend gapi:groovy.lang.Script[] and be a single abstract method type:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=baseclass_def,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=baseclass_def,indent=0]
 ----
 
 Then the custom script base class can be declared in the compiler configuration, for example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=use_custom_conf,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=use_custom_conf,indent=0]
 ----
 <1> create a custom compiler configuration
 <2> set the base script class to our custom base script class
@@ -203,7 +203,7 @@ As an alternative, it is also possible to use the `@BaseScript` annotation direc
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=use_basescript,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=use_basescript,indent=0]
 ----
 
 where `@BaseScript` should annotate a variable which type is the class of the base script. Alternatively, you can set
@@ -211,7 +211,7 @@ the base script class as a member of the `@BaseScript` annotation itself:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=use_basescript_alt,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=use_basescript_alt,indent=0]
 ----
 
 === Alternate abstract method
@@ -224,7 +224,7 @@ is possible by doing this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=custom_run_method,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=custom_run_method,indent=0]
 ----
 <1> the base script class should define one (and only one) abstract method
 <2> the `run` method can be overridden and perform a task before executing the script body
@@ -235,7 +235,7 @@ If you execute this code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=custom_run_eval,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=custom_run_eval,indent=0]
 ----
 
 Then you will see that the script is executed, but the result of the evaluation is `1` as returned by the `run`
@@ -244,7 +244,7 @@ execute the `run` method several times on the same script instance:
 
 [source,groovy]
 ----
-include::{includedir}/../test/BaseScriptSpecTest.groovy[tags=custom_run_parse,indent=0]
+include::{projectdir}/src/spec/test/BaseScriptSpecTest.groovy[tags=custom_run_parse,indent=0]
 ----
 
 == Adding properties to numbers
@@ -258,7 +258,7 @@ An illustration of this can be found in Groovy using the `TimeCategory`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/CategoryTest.groovy[tags=time_category,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/CategoryTest.groovy[tags=time_category,indent=0]
 ----
 <1> using the `TimeCategory`, a property `minute` is added to the `Integer` class
 <2> similarily, the `months` method returns a `groovy.time.DatumDependentDuration` which can be used in calculus
@@ -283,7 +283,7 @@ code:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
 ---------------------------------------
 
 One way of implementing this is using the builder strategy, which
@@ -297,7 +297,7 @@ Implementing such a builder is usually done the following way:
 
 [source,groovy]
 ----------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=email_method_no_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=email_method_no_delegatesto,indent=0]
 ----------------------------------------------
 
 the `EmailSpec` class implements the `from`, `to`, … methods. By
@@ -309,7 +309,7 @@ resolved only against the delegate of the closure.
 
 [source,groovy]
 ----------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=emailspec_no_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=emailspec_no_delegatesto,indent=0]
 ----------------------------------------------
 
 The `EmailSpec` class has itself a `body` method accepting a closure that is cloned and executed. This is what
@@ -335,7 +335,7 @@ checking on this code:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=email_builder_usage,indent=0]
 ---------------------------------------
 
 Then the type checker will know that there’s an `email` method accepting
@@ -347,7 +347,7 @@ runtime, be of type `EmailSpec`:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_nodelegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_nodelegatesto,indent=0]
 ---------------------------------------
 
 will fail compilation with errors like this one:
@@ -372,7 +372,7 @@ The idea is to annotate the `Closure` parameter of the `email` method:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto,indent=0]
 ---------------------------------------
 
 What we’ve done here is telling the compiler (or the IDE) that when the
@@ -384,7 +384,7 @@ the delegation strategy is also changed:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto_strategy,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=email_method_delegatesto_strategy,indent=0]
 ---------------------------------------
 
 Now, both the IDE and the type checker (if you are using `@TypeChecked`)
@@ -397,7 +397,7 @@ The following code will now pass compilation:
 
 [source,groovy]
 ---------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_pass,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=sendmail_typechecked_pass,indent=0]
 ---------------------------------------
 
 [[TheDelegatesToannotation-DelegatesTomodes]]
@@ -418,7 +418,7 @@ checker).
 
 [source,groovy]
 -----------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=simple_delegation,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=simple_delegation,indent=0]
 -----------------------------------------------
 
 [[TheDelegatesToannotation-Delegationstrategy]]
@@ -430,7 +430,7 @@ with the default delegation strategy, which is `Closure.OWNER_FIRST`.
 
 [source,groovy]
 ----------------------------------------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegation_with_strategy,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegation_with_strategy,indent=0]
 ----------------------------------------------------------------------------------
 
 [[TheDelegatesToannotation-Delegatetoparameter]]
@@ -441,7 +441,7 @@ another parameter of the method. Take the following code:
 
 [source,groovy]
 -------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=exec_method_no_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=exec_method_no_delegatesto,indent=0]
 -------------------------------------------------
 
 Here, the delegate which will be used is *not* created inside the `exec`
@@ -450,7 +450,7 @@ Usage may look like this:
 
 [source,groovy]
 -----------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=exec_usage,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=exec_usage,indent=0]
 -----------------------
 
 Each of the method calls are delegated to the `email` parameter. This is
@@ -459,7 +459,7 @@ companion annotation:
 
 [source,groovy]
 ---------------------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=exec_method_with_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=exec_method_with_delegatesto,indent=0]
 ---------------------------------------------------------------
 
 A closure is annotated with `@DelegatesTo`, but this time, without
@@ -470,8 +470,8 @@ which in this case is `Object` but this is not true. Take this code:
 
 [source,groovy]
 --------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_header,indent=0]
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_footer,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_header,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegatesto_flow_typing_footer,indent=0]
 --------------------------------------
 
 Remember that this works out of the box *without* having to annotate
@@ -495,7 +495,7 @@ but you may have methods that take multiple closures:
 
 [source,groovy]
 --------------------------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_no_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_no_delegatesto,indent=0]
 --------------------------------------------------------------------
 
 Then nothing prevents you from annotating each closure
@@ -503,11 +503,11 @@ with `@DelegatesTo`:
 
 [source,groovy]
 --------------------------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=foobarbaz_classes,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=foobarbaz_classes,indent=0]
 
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_header,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_header,indent=0]
    ...
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_footer,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=foobarbaz_method_footer,indent=0]
 --------------------------------------------------------------------
 
 But more importantly, if you have multiple closures *and* multiple
@@ -515,9 +515,9 @@ arguments, you can use several targets:
 
 [source,groovy]
 -----------------------------------------------------------------------------
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=foobarbaz_multitarget,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=foobarbaz_multitarget,indent=0]
 
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=multitarget_test,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=multitarget_test,indent=0]
 -----------------------------------------------------------------------------
 
 NOTE: At this point, you may wonder why we don’t use the parameter names as
@@ -532,14 +532,14 @@ but a generic type. Imagine a configurator that runs on a list of elements:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=configure_list_method,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=configure_list_method,indent=0]
 ----
 
 Then this method can be called with any list like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=configure_list_usage,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=configure_list_usage,indent=0]
 ----
 
 To let the type checker and the IDE know that the `configure` method calls the closure on each element of the list, you
@@ -547,7 +547,7 @@ To let the type checker and the IDE know that the `configure` method calls the c
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=configure_list_with_delegatesto,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=configure_list_with_delegatesto,indent=0]
 ----
 
 `@DelegatesTo` takes an optional `genericTypeIndex` argument that tells what is the index of the generic type that will
@@ -564,7 +564,7 @@ a mapper class which is parametrized with an object and defines a map method whi
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper,indent=0]
 ----
 <1> The mapper class takes two generic type arguments: the source type and the target type
 <2> The source object is stored in a final field
@@ -577,7 +577,7 @@ available options for `@DelegatesTo` is suitable. For example, if we try to stat
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_test,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_test,indent=0]
 ----
 
 Then the compiler will fail with:
@@ -590,7 +590,7 @@ In that case, you can use the `type` member of the `@DelegatesTo` annotation to
 
 [source,groovy]
 ----
-include::{includedir}/../test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_fixed,indent=0]
+include::{projectdir}/src/spec/test/DelegatesToSpecTest.groovy[tags=delegatestotype_mapper_fixed,indent=0]
 ----
 <1> The `@DelegatesTo` annotation references a generic type which is not found in the method signature
 
@@ -648,7 +648,7 @@ Groovy language allows, that is:
 -----------------------------------------------------------------------------------------------------
 import org.codehaus.groovy.control.customizers.ImportCustomizer
 
-include::{includedir}/../test/CustomizersTest.groovy[tags=import_cz,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=import_cz,indent=0]
 -----------------------------------------------------------------------------------------------------
 
 A detailed description of all shortcuts can be found in gapi:org.codehaus.groovy.control.customizers.ImportCustomizer[]
@@ -675,7 +675,7 @@ to do it:
 import org.codehaus.groovy.control.customizers.ASTTransformationCustomizer
 import groovy.util.logging.Log
 
-include::{includedir}/../test/CustomizersTest.groovy[tags=ast_cz_simple,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=ast_cz_simple,indent=0]
 --------------------------------------------------------------------------
 
 That’s all! Internally, the `@Log` AST transformation is applied to
@@ -687,7 +687,7 @@ use parameters in the constructor too:
 
 [source,groovy]
 -----------------------------------------------------------------------------------------------------------------
-include::{includedir}/../test/CustomizersTest.groovy[tags=ast_cz_customname,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=ast_cz_customname,indent=0]
 -----------------------------------------------------------------------------------------------------------------
 
 As the AST transformation customizers works with objects instead of AST
@@ -699,7 +699,7 @@ give it a `ClosureExpression`, like in the following example:
 
 [source,groovy]
 --------------------------------------------------------------------------------------------------------------
-include::{rootprojectdir}/subprojects/groovy-astbuilder/src/spec/test/CustomizersTest.groovy[tags=ast_cz_closure,indent=0]
+include::{projectdir}/subprojects/groovy-astbuilder/src/spec/test/CustomizersTest.groovy[tags=ast_cz_closure,indent=0]
 --------------------------------------------------------------------------------------------------------------
 
 For a complete list of options, please refer to gapi:org.codehaus.groovy.control.customizers.ASTTransformationCustomizer[]
@@ -740,7 +740,7 @@ you will choose allowed lists (which permits only the constructs listed and disa
 import org.codehaus.groovy.control.customizers.SecureASTCustomizer
 import static org.codehaus.groovy.syntax.Types.* <1>
 
-include::{includedir}/../test/CustomizersTest.groovy[tags=secure_cz,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=secure_cz,indent=0]
 -------------------------------------------------------------------------------------
 <1> use for token types from gapi:org.codehaus.groovy.syntax.Types[]
 <2> you can use class literals here
@@ -765,7 +765,7 @@ checker, it is trivial:
 
 [source,groovy]
 ----------------------------------------------------------------------
-include::{includedir}/../test/CustomizersTest.groovy[tags=secure_cz_custom,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=secure_cz_custom,indent=0]
 ----------------------------------------------------------------------
 
 Then we can make sure that this works by evaluating a simple script:
@@ -773,7 +773,7 @@ Then we can make sure that this works by evaluating a simple script:
 [source,groovy]
 ----
 new GroovyShell(config).evaluate '''
-include::{includedir}/../test/CustomizersTest.groovy[tags=secure_cz_custom_assert,indent=4]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=secure_cz_custom_assert,indent=4]
 '''
 ----
 <1> will fail compilation
@@ -799,14 +799,14 @@ example. Here is how you would create a source aware customizer:
 import org.codehaus.groovy.control.customizers.SourceAwareCustomizer
 import org.codehaus.groovy.control.customizers.ImportCustomizer
 
-include::{includedir}/../test/CustomizersTest.groovy[tags=source_cz,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=source_cz,indent=0]
 --------------------------------------------------------------------
 
 Then you can use predicates on the source aware customizer:
 
 [source,groovy]
 --------------------------------------------------------------------------
-include::{includedir}/../test/CustomizersTest.groovy[tags=source_cz_predicates,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=source_cz_predicates,indent=0]
 --------------------------------------------------------------------------
 
 === Customizer builder
@@ -821,7 +821,7 @@ simplifies the creation of customizers using a hierarchical DSL.
 import org.codehaus.groovy.control.CompilerConfiguration
 import static org.codehaus.groovy.control.customizers.builder.CompilerCustomizationBuilder.withConfig <1>
 
-include::{includedir}/../test/CustomizersTest.groovy[tags=customizer_withconfig,indent=0]
+include::{projectdir}/src/spec/test/CustomizersTest.groovy[tags=customizer_withconfig,indent=0]
 -----------------------------------------------------------------------------------------------------
 <1> static import of the builder method
 <2> configuration goes here
@@ -1014,7 +1014,7 @@ Then AST transformations are the way to go. Unlike the techniques used so far, A
 change or generate code before it is compiled to bytecode. AST transformations are capable of adding new methods at
 compile time for example, or totally changing the body of a method based on your needs. They are a very powerful tool
 but also come at the price of not being easy to write. For more information about AST transformations, please take
-a look at the https://docs.groovy-lang.org/latest/html/documentation/index.html#_compile_time_metaprogramming[compile-time
+a look at the http://docs.groovy-lang.org/latest/html/documentation/index.html#_compile_time_metaprogramming[compile-time
 metaprogramming] section of this manual.
 
 == Custom type checking extensions
@@ -1052,11 +1052,11 @@ See <<xml-userguide.adoc#_markupbuilder,Creating Xml - MarkupBuilder>>.
 
 See <<xml-userguide.adoc#_streamingmarkupbuilder,Creating Xml - StreamingMarkupBuilder>>.
 
-include::{rootprojectdir}/subprojects/groovy-xml/{specfolder}/fragment_sax-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-xml/{specfolder}/sax-builder.adoc[leveloffset=+3]
 
-include::{rootprojectdir}/subprojects/groovy-xml/{specfolder}/fragment_stax-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-xml/{specfolder}/stax-builder.adoc[leveloffset=+3]
 
-include::{rootprojectdir}/subprojects/groovy-xml/{specfolder}/fragment_dom-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-xml/{specfolder}/dom-builder.adoc[leveloffset=+3]
 
 ==== NodeBuilder
 
@@ -1065,23 +1065,23 @@ To create a simple user list you use a `NodeBuilder` like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/NodeBuilderTest.groovy[tags=node_builder_example,indent=0]
+include::{projectdir}/src/spec/test/builder/NodeBuilderTest.groovy[tags=node_builder_example,indent=0]
 ----
 
-Now you can process the data further, e.g. by using <<core-semantics.adoc#gpath_expressions,GPath expressions>>:
+Now you can process the data further, e.g. by using <<gpath_expressions,GPath expressions>>: 
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/NodeBuilderTest.groovy[tags=node_builder_gpath_assert,indent=0]
+include::{projectdir}/src/spec/test/builder/NodeBuilderTest.groovy[tags=node_builder_gpath_assert,indent=0]
 ----
 
-include::{rootprojectdir}/subprojects/groovy-json/{specfolder}/fragment_json-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-json/{specfolder}/json-builder.adoc[leveloffset=+3]
 
-include::{rootprojectdir}/subprojects/groovy-json/{specfolder}/fragment_streaming-jason-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-json/{specfolder}/streaming-jason-builder.adoc[leveloffset=+3]
 
-include::{rootprojectdir}/subprojects/groovy-swing/{specfolder}/fragment_swing-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-swing/{specfolder}/swing-builder.adoc[leveloffset=+3]
 
-include::{rootprojectdir}/subprojects/groovy-ant/{specfolder}/fragment_ant-builder.adoc[leveloffset=+3]
+include::{projectdir}/subprojects/groovy-ant/{specfolder}/ant-builder.adoc[leveloffset=+3]
 
 ==== CliBuilder
 
@@ -1211,7 +1211,7 @@ Here is how such a specification can be defined:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/GreeterI.groovy[tags=annotationInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/GreeterI.groovy[tags=annotationInterfaceSpec,indent=0]
 ----
 <1> Specify a Boolean option set using `-h` or `--help`
 <2> Specify a String option set using `-a` or `--audience`
@@ -1226,7 +1226,7 @@ Here is how you could use the interface specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=annotationInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=annotationInterface,indent=0]
 ----
 <1> Create a `CliBuilder` instance as before with optional properties
 <2> Parse parameters using the interface specification
@@ -1248,7 +1248,7 @@ Here is how such a specification can be defined:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/GreeterC.groovy[tags=annotationClassSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/GreeterC.groovy[tags=annotationClassSpec,indent=0]
 ----
 <1> Indicate that a Boolean property is an option
 <2> Indicate that a String property (with explicit setter) is an option
@@ -1258,7 +1258,7 @@ And here is how you could use the specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=annotationClass,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=annotationClass,indent=0]
 ----
 <1> Create a `CliBuilder` instance as before with optional parameters
 <2> Create an instance for `CliBuilder` to populate
@@ -1282,7 +1282,7 @@ with the same arguments as shown for the instance example earlier:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=annotationScript,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=annotationScript,indent=0]
 ----
 
 ===== Options with arguments
@@ -1294,7 +1294,7 @@ Here is an example involving those cases:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withArgument,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withArgument,indent=0]
 ----
 <1> An option that is simply a flag - the default; setting args to 0 is allowed but not needed.
 <2> An option with exactly one argument
@@ -1311,14 +1311,14 @@ illustrating such a definition:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/WithArgsI.groovy[tags=withArgumentInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/WithArgsI.groovy[tags=withArgumentInterfaceSpec,indent=0]
 ----
 
 And here is how it is used:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withArgumentInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withArgumentInterface,indent=0]
 ----
 
 This example makes use of an array-typed option specification. We cover this in more detail shortly when we discuss
@@ -1339,7 +1339,7 @@ Here is an example using types with the dynamic api argument definition style:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withType,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withType,indent=0]
 ----
 
 Primitives, numeric types, files, enums and arrays thereof, are supported (they are converted using
@@ -1352,7 +1352,7 @@ for you. Here is a sample using the dynamic api style:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withConvert,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withConvert,indent=0]
 ----
 
 Alternatively, you can use the annotation style by supplying the conversion closure as an annotation parameter.
@@ -1360,14 +1360,14 @@ Here is an example specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/WithConvertI.groovy[tags=withConvertInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/WithConvertI.groovy[tags=withConvertInterfaceSpec,indent=0]
 ----
 
 And an example using that specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withConvertInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withConvertInterface,indent=0]
 ----
 
 ===== Options with multiple arguments
@@ -1393,7 +1393,7 @@ Here is an excerpt highlighting the use of multiple arguments:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=multipleArgs,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=multipleArgs,indent=0]
 ----
 <1> Args value supplied as a String and comma value separator specified
 <2> One or more arguments are allowed
@@ -1413,14 +1413,14 @@ array type for the annotated class member (method or property) as this example s
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/ValSepI.groovy[tags=multipleArgsInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/ValSepI.groovy[tags=multipleArgsInterfaceSpec,indent=0]
 ----
 
 And used as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=multipleArgsInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=multipleArgsInterface,indent=0]
 ----
 
 ===== Types and multiple arguments
@@ -1429,7 +1429,7 @@ Here is an example using types and multiple arguments with the dynamic api argum
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withTypeMultiple,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withTypeMultiple,indent=0]
 ----
 <1> For an array type, the trailing 's' can be used but isn't needed
 
@@ -1444,7 +1444,7 @@ Here is how you could use it using the dynamic api style:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withDefaultValue,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withDefaultValue,indent=0]
 ----
 
 Similarly, you might want such a specification using the annotation style. Here is an example using an interface
@@ -1452,14 +1452,14 @@ specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/WithDefaultValueI.groovy[tags=withDefaultValueInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/WithDefaultValueI.groovy[tags=withDefaultValueInterfaceSpec,indent=0]
 ----
 
 Which would be used like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withDefaultValueInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withDefaultValueInterface,indent=0]
 ----
 
 You can also use the `defaultValue` annotation attribute when using annotations with an instance,
@@ -1473,14 +1473,14 @@ annotation style, for example, here is an interface option specification:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/TypeCheckedI.groovy[tags=withTypeCheckedInterfaceSpec,indent=0]
+include::{projectdir}/src/spec/test/cli/TypeCheckedI.groovy[tags=withTypeCheckedInterfaceSpec,indent=0]
 ----
 
 And it can be used in combination with `@TypeChecked` as shown here:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withTypeCheckedInterface,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withTypeCheckedInterface,indent=0]
 ----
 
 Secondly, there is a feature of the dynamic api style which offers some support. The definition statements
@@ -1513,7 +1513,7 @@ the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/cli/CliBuilderTestCase.groovy[tags=withTypeChecked,indent=0]
+include::{projectdir}/src/spec/test/cli/CliBuilderTestCase.groovy[tags=withTypeChecked,indent=0]
 ----
 
 ===== Advanced CLI Usage
@@ -1594,7 +1594,7 @@ which gives fine-grained control over various sections of the usage help message
 
 [source,groovy]
 ----
-include::{rootprojectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=withUsageMessageSpec,indent=0]
+include::{projectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=withUsageMessageSpec,indent=0]
 ----
 Gives this output:
 
@@ -1631,9 +1631,9 @@ Finally, if your application has options that are key-value pairs, you may be in
 
 [source,groovy]
 ----
-include::{rootprojectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOptionImports,indent=0]
+include::{projectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOptionImports,indent=0]
 
-include::{rootprojectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOption,indent=0]
+include::{projectdir}/subprojects/groovy-cli-picocli/src/spec/test/builder/CliBuilderTest.groovy[tags=mapOption,indent=0]
 ----
 <1> Previously, `key=value` pairs were split up into parts and added to a list
 <2> Picocli map support: simply specify `Map` as the type of the option
@@ -1666,7 +1666,7 @@ Let's start with a list of classes that belong to your domain:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=domain_classes,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=domain_classes,indent=0]
 ----
 
 Then using `ObjectGraphBuilder` building a `Company` with three employees is as
@@ -1674,7 +1674,7 @@ easy as:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=builder_example,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=builder_example,indent=0]
 ----
 <1> creates a new object graph builder
 <2> sets the classloader where the classes will be resolved
@@ -1700,27 +1700,27 @@ immutable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_class,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_class,indent=0]
 ----
 
 Then if you try to create a `Person` with the builder:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_fail_runtime,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=immutable_fail_runtime,indent=0]
 ----
 
 It will fail at runtime with:
 
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=expected_error_immutable,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=expected_error_immutable,indent=0]
 ----
 
 Fixing this can be done by changing the new instance strategy:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=newinstanceresolver,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=newinstanceresolver,indent=0]
 ----
 
 `ObjectGraphBuilder` supports ids per node, meaning
@@ -1735,7 +1735,7 @@ appropriate value (default is `refId'):
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/ObjectGraphBuilderTest.groovy[tags=test_id,indent=0]
+include::{projectdir}/src/spec/test/builder/ObjectGraphBuilderTest.groovy[tags=test_id,indent=0]
 ----
 <1> an address can be created with an `id`
 <2> an employee can reference the address directly with its id
@@ -1746,7 +1746,7 @@ referenced bean.
 
 ==== JmxBuilder
 
-See <<jmx.adoc#jmx_jmxbuilder,Working with JMX - JmxBuilder>> for details.
+See <<jmx_jmxbuilder,Working with JMX - JmxBuilder>> for details.
 
 ==== FileTreeBuilder
 
@@ -1766,26 +1766,26 @@ You can use a `FileTreeBuilder` like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/FileTreeBuilderTest.groovy[tags=example,indent=0]
+include::{projectdir}/src/spec/test/builder/FileTreeBuilderTest.groovy[tags=example,indent=0]
 ----
 
 To check that everything worked as expected we use the following `assert`s:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/FileTreeBuilderTest.groovy[tags=example_assert,indent=0]
+include::{projectdir}/src/spec/test/builder/FileTreeBuilderTest.groovy[tags=example_assert,indent=0]
 ----
 
 `FileTreeBuilder` also supports a shorthand syntax:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax,indent=0]
+include::{projectdir}/src/spec/test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax,indent=0]
 ----
 
 This produces the same directory structure as above, as shown by these `assert`s:
 
 [source,groovy]
 ----
-include::{includedir}/../test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax_assert,indent=0]
+include::{projectdir}/src/spec/test/builder/FileTreeBuilderTest.groovy[tags=shorthand_syntax_assert,indent=0]
 ----
diff --git a/src/spec/doc/core-gdk.adoc b/src/spec/doc/core-gdk.adoc
index d8d846a..7a79e0b 100644
--- a/src/spec/doc/core-gdk.adoc
+++ b/src/spec/doc/core-gdk.adoc
@@ -21,14 +21,13 @@
 
 = Groovy Development Kit
 
+include::{projectdir}/src/spec/doc/working-with-io.adoc[leveloffset=+1]
 
-include::{includedir}/fragment_working-with-io.adoc[leveloffset=+1]
+include::{projectdir}/src/spec/doc/working-with-collections.adoc[leveloffset=+1]
 
-include::{includedir}/fragment_working-with-collections.adoc[leveloffset=+1]
+include::{projectdir}/subprojects/groovy-dateutil/{specfolder}/working-with-dateutil-types.adoc[leveloffset=+1]
 
-include::{rootprojectdir}/subprojects/groovy-dateutil/{specfolder}/fragment_working-with-dateutil-types.adoc[leveloffset=+1]
-
-include::{rootprojectdir}/subprojects/groovy-datetime/{specfolder}/fragment_working-with-datetime-types.adoc[leveloffset=+1]
+include::{projectdir}/subprojects/groovy-datetime/{specfolder}/working-with-datetime-types.adoc[leveloffset=+1]
 
 == Handy utilities
 
@@ -40,7 +39,7 @@ configuration values and arbitrary object types.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=arbitrary_types,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=arbitrary_types,indent=0]
 ----
 <1> Usage of the dot notation
 <2> Usage of Closure scopes as an alternative to the dot notation
@@ -51,7 +50,7 @@ instance but never `null`.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=never_null,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=never_null,indent=0]
 ----
 <1> `config.test` has not been specified yet it returns a `ConfigObject` when being called.
 
@@ -59,7 +58,7 @@ In the case of a dot being part of a configuration variable name, it can be esca
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=escape_dot,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=escape_dot,indent=0]
 ----
 
 In addition, `ConfigSlurper` comes with support for `environments`. The `environments` method can be used to hand over
@@ -69,7 +68,7 @@ constructor to specify the target environment.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=environments,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=environments,indent=0]
 ----
 
 [NOTE]
@@ -81,7 +80,7 @@ in addition to the `environments` name.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=custom_environments,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=custom_environments,indent=0]
 ----
 <1> Once the new block is registered `ConfigSlurper` can parse it.
 
@@ -91,7 +90,7 @@ object that might be stored to a `*.properties` text file. Be aware though that
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ConfigSlurperTest.groovy[tags=properties,indent=0]
+include::{projectdir}/src/spec/test/gdk/ConfigSlurperTest.groovy[tags=properties,indent=0]
 ----
 
 === Expando
@@ -102,7 +101,7 @@ extended with properties (or methods) at runtime.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ExpandoTest.groovy[tags=expando_property,indent=0]
+include::{projectdir}/src/spec/test/gdk/ExpandoTest.groovy[tags=expando_property,indent=0]
 ----
 
 A special case occurs when a dynamic property registers a `Closure` code block. Once being registered it can be invoked
@@ -110,7 +109,7 @@ as it would be done with a method call.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ExpandoTest.groovy[tags=expando_method,indent=0]
+include::{projectdir}/src/spec/test/gdk/ExpandoTest.groovy[tags=expando_method,indent=0]
 ----
 
 === Observable list, map and set
@@ -124,7 +123,7 @@ Depending on the type of change that has happened, observable collections might
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ObservableTest.groovy[tags=observable_list,indent=0]
+include::{projectdir}/src/spec/test/gdk/ObservableTest.groovy[tags=observable_list,indent=0]
 ----
 <1> Declares a `PropertyChangeEventListener` that is capturing the fired events
 <2> `ObservableList.ElementEvent` and its descendant types are relevant for this listener
@@ -141,7 +140,7 @@ The `ObservableList.ElementClearedEvent` event type is another interesting one.
 
 [source,groovy]
 ----
-include::{includedir}/../test/gdk/ObservableTest.groovy[tags=observable_list_clear,indent=0]
+include::{projectdir}/src/spec/test/gdk/ObservableTest.groovy[tags=observable_list_clear,indent=0]
 ----
 
 To get an overview of all the supported event types the reader is encouraged to have a look at the JavaDoc documentation
diff --git a/src/spec/doc/core-getting-started.adoc b/src/spec/doc/core-getting-started.adoc
index 4bb5185..1206048 100644
--- a/src/spec/doc/core-getting-started.adoc
+++ b/src/spec/doc/core-getting-started.adoc
@@ -25,7 +25,7 @@
 
 In this download area, you will be able to download the distribution (binary and source), the Windows installer and the documentation for **Groovy**.
 
-For a quick and effortless start on Mac OSX, Linux or Cygwin, you can use https://sdkman.io/[SDKMAN!] (The Software Development Kit Manager) to download and configure any **Groovy** version of your choice. Basic <<SDKMAN,instructions>> can be found below.
+For a quick and effortless start on Mac OSX, Linux or Cygwin, you can use http://sdkman.io/[SDKMAN!] (The Software Development Kit Manager) to download and configure any **Groovy** version of your choice. Basic <<SDKMAN,instructions>> can be found below.
 
 === Stable
 
@@ -33,7 +33,7 @@ For a quick and effortless start on Mac OSX, Linux or Cygwin, you can use https:
 - **Download documentation**: https://bintray.com/artifact/download/groovy/maven/apache-groovy-docs-{groovy-full-version}.zip[**JavaDoc and zipped online documentation**]
 - **Combined binary / source / documentation bundle**: https://bintray.com/artifact/download/groovy/maven/apache-groovy-sdk-{groovy-full-version}.zip[**Distribution bundle**]
 
-You can learn more about this version in the https://groovy-lang.org/releasenotes/groovy-{groovy-short-version}.html[release notes] or in the https://groovy-lang.org/changelogs/changelog-{groovy-full-version}.html[changelog].
+You can learn more about this version in the http://groovy-lang.org/releasenotes/groovy-{groovy-short-version}.html[release notes] or in the http://groovy-lang.org/changelogs/changelog-{groovy-full-version}.html[changelog].
 
 If you plan on using invokedynamic support, link:invokedynamic-support.html[read those notes].
 
@@ -129,7 +129,7 @@ That's all there is to it!
 
 ==== MacPorts
 
-If you're on MacOS and have https://www.macports.org[MacPorts] installed, you can run:
+If you're on MacOS and have http://www.macports.org[MacPorts] installed, you can run:
 
 [source,shell]
 ----
@@ -138,7 +138,7 @@ sudo port install groovy
 
 ==== Homebrew
 
-If you're on MacOS and have https://mxcl.github.com/homebrew[Homebrew] installed, you can run:
+If you're on MacOS and have http://mxcl.github.com/homebrew[Homebrew] installed, you can run:
 
 [source,shell]
 ----
@@ -165,7 +165,7 @@ If you are an IDE user, you can just grab the latest link:tools-ide.html[IDE plu
 
 These instructions describe how to install a binary distribution of **Groovy**.
 
-* First, https://groovy.apache.org/download.html[Download] a binary distribution of Groovy and unpack it into some file on your local file system.
+* First, <<download-groovy,Download>> a binary distribution of Groovy and unpack it into some file on your local file system.
 * Set your `GROOVY_HOME` environment variable to the directory you unpacked the distribution.
 * Add `GROOVY_HOME/bin` to your `PATH` environment variable.
 * Set your `JAVA_HOME` environment variable to point to your JDK. On OS X this is `/Library/Java/Home`, on other unixes its often `/usr/java` etc. If you've already installed tools like Ant or Maven you've probably already done this step.
diff --git a/src/spec/doc/core-metaprogramming.adoc b/src/spec/doc/core-metaprogramming.adoc
index 028e63f..5d34f41 100644
--- a/src/spec/doc/core-metaprogramming.adoc
+++ b/src/spec/doc/core-metaprogramming.adoc
@@ -71,7 +71,7 @@ overridden `invokeMethod()` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_invoke_method,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_invoke_method,indent=0]
 ----
 
 However, the use of `invokeMethod` to intercept missing methods is discouraged.  In cases where the intent is to only
@@ -85,7 +85,7 @@ Here is a simple example:
 
 [source, groovy]
 ----
-include::{includedir}/../test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_get_property,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_get_property,indent=0]
 ----
 <1> Forwards the request to the getter for all properties except `field3`.
 
@@ -93,7 +93,7 @@ You can intercept write access to properties by overriding the `setProperty()` m
 
 [source, groovy]
 ----
-include::{includedir}/../test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_set_property,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_set_property,indent=0]
 ----
 
 ==== get/setMetaClass
@@ -118,12 +118,12 @@ This functionality is related to the `MetaClass` implementation. In the default
 
 [source, groovy]
 ----
-include::{includedir}/../test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_get_attribute,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_get_attribute,indent=0]
 ----
 
 [source, groovy]
 ----
-include::{includedir}/../test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_set_attribute,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/GroovyObjectTest.groovy[tags=groovy_set_attribute,indent=0]
 ----
 
 === methodMissing
@@ -134,7 +134,7 @@ given arguments:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MethodPropertyMissingTest.groovy[tags=method_missing_simple,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MethodPropertyMissingTest.groovy[tags=method_missing_simple,indent=0]
 ----
 
 Typically when using `methodMissing` it is possible to cache the result for the next time the same method is called.
@@ -172,7 +172,7 @@ case of a getter method, `propertyMissing` takes a single `String` argument cont
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MethodPropertyMissingTest.groovy[tags=property_missing_getter,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MethodPropertyMissingTest.groovy[tags=property_missing_getter,indent=0]
 ----
 
 The `propertyMissing(String)` method is only called when no getter method for the given property can be found by the Groovy
@@ -182,7 +182,7 @@ For setter methods a second `propertyMissing` definition can be added that takes
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MethodPropertyMissingTest.groovy[tags=property_missing_getter_setter,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MethodPropertyMissingTest.groovy[tags=property_missing_getter_setter,indent=0]
 ----
 
 As with `methodMissing` it is best practice to dynamically register new properties at runtime to improve the overall lookup
@@ -195,7 +195,7 @@ or can be implemented at the class level with `$static_methodMissing` method.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/StaticPropertyMissingAndMethodMissingTest.groovy[tags=static_method_missing,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/StaticPropertyMissingAndMethodMissingTest.groovy[tags=static_method_missing,indent=0]
 ----
 
 === static propertyMissing
@@ -205,7 +205,7 @@ or can be implemented at the class level with `$static_propertyMissing` method.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/StaticPropertyMissingAndMethodMissingTest.groovy[tags=static_property_missing,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/StaticPropertyMissingAndMethodMissingTest.groovy[tags=static_property_missing,indent=0]
 ----
 
 === GroovyInterceptable
@@ -222,14 +222,14 @@ When a Groovy object implements the `GroovyInterceptable` interface, its `invoke
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_object_example,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_object_example,indent=0]
 ----
 
 The next piece of code is a test which shows that both calls to existing and non-existing methods will return the same value.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_test,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/InterceptableTest.groovy[tags=groovy_interceptable_test,indent=0]
 ----
 
 [NOTE]
@@ -240,7 +240,7 @@ This approach works for both POGOs and POJOs, as shown by this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/InterceptionThroughMetaClassTest.groovy[tags=meta_class_interception,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/InterceptionThroughMetaClassTest.groovy[tags=meta_class_interception,indent=0]
 ----
 
 [NOTE]
@@ -267,7 +267,7 @@ the scoped `use` method that is provided by the GDK and available from inside ev
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/CategoryTest.groovy[tags=time_category,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/CategoryTest.groovy[tags=time_category,indent=0]
 ----
 <1> `TimeCategory` adds methods to `Integer`
 <2> `TimeCategory` adds methods to `Date`
@@ -279,7 +279,7 @@ like `java.lang.Integer` or `java.util.Date` can be enriched with user-defined m
 A category needs not to be directly exposed to the user code, the following will also do:
 
 [source,groovy]
-----
+----------------------------------------------------------------------------------------------------------------------
 class JPACategory{
   // Let's enhance JPA EntityManager without getting into the JSR committee
   static void persistAll(EntityManager em , Object[] entities) { //add an interface to save all
@@ -310,14 +310,14 @@ transactionContext (em) {
  // let's do some logics here to make the example sensible
  em.persistAll(obj2, obj4, obj6)
 }
-----
+----------------------------------------------------------------------------------------------------------------------
 
 When we have a look at the `groovy.time.TimeCategory` class we see that the extension methods are all declared as `static`
 methods. In fact, this is one of the requirements that must be met by category classes for its methods to be successfully added to
 a class inside the `use` code block:
 
 [source,groovy]
-----
+----------------------------------------------------------------------------------------------------------------------
 public class TimeCategory {
 
     public static Date plus(final Date date, final BaseDuration duration) {
@@ -340,7 +340,7 @@ public class TimeCategory {
     }
 
     // ...
-----
+----------------------------------------------------------------------------------------------------------------------
 
 Another requirement is the first argument of the static method must define the type the method is attached to once being activated. The
 other arguments are the normal arguments the method will take as parameters.
@@ -351,7 +351,7 @@ into category classes at compile-time.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/CategoryTest.groovy[tags=time_category_anno,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/CategoryTest.groovy[tags=time_category_anno,indent=0]
 ----
 
 Applying the `@Category` annotation has the advantage of being able to use instance methods without the target type as a
@@ -521,7 +521,7 @@ The operators are applied on a non-existent property of `metaClass` passing an i
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_method,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_method,indent=0]
 ----
 
 The example above shows how a new method can be added to a class by accessing the `metaClass` property and using the `<<` or
@@ -536,14 +536,14 @@ Firstly, it has support for declaring a _mutable property_ by simply assigning a
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_property,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_property,indent=0]
 ----
 
 Another way is to add getter and/or setter methods by using the standard mechanisms for adding instance methods.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_getter,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_getter,indent=0]
 ----
 
 In the source code example above the property is dictated by the closure and is a read-only property. It is feasible to add
@@ -552,7 +552,7 @@ shown in the following example.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_getter_setter,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_getter_setter,indent=0]
 ----
 
 This is not the only technique however. For example in a servlet container one way might be to store the values in
@@ -566,7 +566,7 @@ executed at runtime.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_constructors,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_constructors,indent=0]
 ----
 
 [NOTE]
@@ -579,7 +579,7 @@ before the method name.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_static,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_static,indent=0]
 ----
 
 ===== Borrowing Methods
@@ -588,7 +588,7 @@ With `ExpandoMetaClass` it is possible to use Groovy's method pointer syntax to
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_method_pointer,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_method_pointer,indent=0]
 ----
 
 ===== Dynamic Method Names
@@ -599,7 +599,7 @@ names as strings.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_dynamic_method_names,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_dynamic_method_names,indent=0]
 ----
 
 The same concept can be applied to static methods and properties.
@@ -609,7 +609,7 @@ codecs" is implemented by using dynamic method names.
 
 [source,groovy]
 .`HTMLCodec` Class
-----
+------------------------------------------------------
 class HTMLCodec {
     static encode = { theTarget ->
         HtmlUtils.htmlEscape(theTarget.toString())
@@ -619,7 +619,7 @@ class HTMLCodec {
     	HtmlUtils.htmlUnescape(theTarget.toString())
     }
 }
-----
+------------------------------------------------------
 
 The example above shows a codec implementation. Grails comes with various codec implementations each defined in a single class.
 At runtime there will be multiple codec classes in the application classpath. At application startup the framework adds
@@ -627,7 +627,7 @@ a `encodeXXX` and a `decodeXXX` method to certain meta-classes where `XXX` is th
 `encodeHTML`). This mechanism is in the following shown in some Groovy pseudo-code:
 
 [source,groovy]
-----
+------------------------------------------------------
 def codecs = classes.findAll { it.name.endsWith('Codec') }
 
 codecs.each { codec ->
@@ -639,7 +639,7 @@ codecs.each { codec ->
 def html = '<html><body>hello</body></html>'
 
 assert '<html><body>hello</body></html>' == html.encodeAsHTML()
-----
+------------------------------------------------------
 
 ===== Runtime Discovery
 
@@ -666,7 +666,7 @@ The following example shows how to override `invokeMethod`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_invoke_method,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_invoke_method,indent=0]
 ----
 
 The first step in the `Closure` code is to lookup the `MetaMethod` for the given name and arguments. If the method
@@ -679,7 +679,7 @@ The same logic can be used to override `setProperty` or `getProperty`.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_get_property,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_get_property,indent=0]
 ----
 
 The important thing to note here is that instead of a `MetaMethod` a `MetaProperty` instance is looked up. If that exists
@@ -691,7 +691,7 @@ the `getProperty` method of the `MetaProperty` is called, passing the delegate.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_invoke_method_static,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_invoke_method_static,indent=0]
 ----
 
 The logic that is used for overriding the static method is the same as we've seen before for overriding instance methods. The
@@ -705,7 +705,7 @@ globally using the `ExpandoMetaClass.enableGlobally()` method before application
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_interface,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ExpandoMetaClassTest.groovy[tags=emc_interface,indent=0]
 ----
 
 === Extension modules
@@ -717,21 +717,21 @@ globally. For example, when you write:
 
 [source,groovy]
 .Standard extension method
-----
+------------------------------------
 def file = new File(...)
 def contents = file.getText('utf-8')
-----
+------------------------------------
 
 The `getText` method doesn’t exist on the `File` class. However, Groovy knows it because it is defined in a special
 class, `ResourceGroovyMethods`:
 
 [source,java]
 .ResourceGroovyMethods.java
-----
+----------------------------------------------------------------------------
 public static String getText(File file, String charset) throws IOException {
  return IOGroovyMethods.getText(newReader(file, charset));
 }
-----
+----------------------------------------------------------------------------
 
 You may notice that the extension method is defined using a static method in a helper class (where various extension
 methods are defined). The first argument of the `getText` method corresponds to the receiver, while additional parameters
@@ -763,7 +763,7 @@ exception is thrown. To do that, you only need to write the following:
 [source,groovy]
 .MaxRetriesExtension.groovy
 ----
-include::{includedir}/../test/support/MaxRetriesExtension.groovy[tags=instance_extension,indent=0]
+include::{projectdir}/src/spec/test/support/MaxRetriesExtension.groovy[tags=instance_extension,indent=0]
 ----
 <1> The extension class
 <2> First argument of the static method corresponds to the receiver of the message, that is to say the extended instance
@@ -772,7 +772,7 @@ Then, after <<module-descriptor,having declared your extension class>>, you can
 
 [source,groovy]
 ----
-include::{includedir}/../test/ExtensionModuleSpecTest.groovy[tags=instance_extension_assert,indent=0]
+include::{projectdir}/src/spec/test/ExtensionModuleSpecTest.groovy[tags=instance_extension_assert,indent=0]
 ----
 
 ==== Static methods
@@ -783,7 +783,7 @@ file. Static and instance extension methods *cannot* be present in the same clas
 [source,groovy]
 .StaticStringExtension.groovy
 ----
-include::{includedir}/../test/support/StaticStringExtension.groovy[tags=static_extension,indent=0]
+include::{projectdir}/src/spec/test/support/StaticStringExtension.groovy[tags=static_extension,indent=0]
 ----
 <1> The static extension class
 <2> First argument of the static method corresponds to the class being extended and is *unused*
@@ -792,7 +792,7 @@ In which case you can call it directly on the `String` class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ExtensionModuleSpecTest.groovy[tags=static_extension_assert,indent=0]
+include::{projectdir}/src/spec/test/ExtensionModuleSpecTest.groovy[tags=static_extension_assert,indent=0]
 ----
 
 [[module-descriptor]]
@@ -805,7 +805,7 @@ your extension helper classes. You must create a file named
 
 .org.codehaus.groovy.runtime.ExtensionModule
 --------------------------------------------------------
-include::{includedir}/../test-resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModuleSpec[tags=extension_descriptor,indent=0]
+include::{projectdir}/src/spec/test-resources/META-INF/groovy/org.codehaus.groovy.runtime.ExtensionModuleSpec[tags=extension_descriptor,indent=0]
 --------------------------------------------------------
 
 The module descriptor requires 4 keys:
@@ -888,9 +888,9 @@ annotating the `Person` class like below will automatically generate the `toStri
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_import,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_import,indent=0]
 
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_simple,indent=0]
 ----
 
 With this definition, then the following assertion passes, meaning that a `toString` method taking the field values from
@@ -898,7 +898,7 @@ the class and printing them out has been generated:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_simple_assert,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_simple_assert,indent=0]
 ----
 
 The `@ToString` annotation accepts several parameters which are summarized in the following table:
@@ -909,63 +909,62 @@ The `@ToString` annotation accepts several parameters which are summarized in th
 |excludes|Empty list|List of properties to exclude from toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_excludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_excludes,indent=0]
 ----
 |includes|Undefined marker list (indicates all fields)|List of fields to include in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includes,indent=0]
 ----
 |includeSuper|False|Should superclass be included in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuper,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuper,indent=0]
 ----
 |includeNames|false|Whether to include names of properties in generated toString.|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeNames,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeNames,indent=0]
 ----
 |includeFields|False|Should fields be included in toString, in addition to properties|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeFields,indent=0]
 ----
 |includeSuperProperties|False|Should super properties be included in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuperProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuperProperties,indent=0]
 ----
 |includeSuperFields|False|Should visible super fields be included in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuperFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includeSuperFields,indent=0]
 ----
 |ignoreNulls|False|Should properties/fields with null value be displayed|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_ignoreNulls,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_ignoreNulls,indent=0]
 ----
 |includePackage|True|Use fully qualified class name instead of simple name in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includePackage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_includePackage,indent=0]
 ----
 |allProperties|True|Include all JavaBean properties in toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_allProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_allProperties,indent=0]
 ----
 |cache|False|Cache the toString string. Should only be set to true if the class is immutable.|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_cache,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_cache,indent=0]
 ----
 |allNames|False|Should fields and/or properties with internal names be included in the generated toString|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_allNames,indent=0]
-----
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tostring_example_allNames,indent=0]
 
 |=======================================================================
 
@@ -977,7 +976,7 @@ hashcode follows the best practices as described in _Effective Java_ by _Josh Bl
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode,indent=0]
 ----
 
 There are several options available to tweak the behavior of `@EqualsAndHashCode`:
@@ -988,38 +987,38 @@ There are several options available to tweak the behavior of `@EqualsAndHashCode
 |excludes|Empty list|List of properties to exclude from equals/hashCode|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_excludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_excludes,indent=0]
 ----
 |includes|Undefined marker list (indicating all fields)|List of fields to include in equals/hashCode|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_includes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_includes,indent=0]
 ----
 |cache|False|Cache the hashCode computation. Should only be set to true if the class is immutable.|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_cache,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_cache,indent=0]
 ----
 |callSuper|False|Whether to include super in equals and hashCode calculations|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_super,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_super,indent=0]
 ----
 |includeFields|False|Should fields be included in equals/hashCode, in addition to properties|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_includeFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_includeFields,indent=0]
 ----
 |useCanEqual|True|Should equals call canEqual helper method.|See http://www.artima.com/lejava/articles/equality.html
 |allProperties|False|Should JavaBean properties be included in equals and hashCode calculations|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_allProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_allProperties,indent=0]
 ----
 |allNames|False|Should fields and/or properties with internal names be included in equals and hashCode calculations|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_allNames,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=equalshashcode_example_allNames,indent=0]
 ----
 |=======================================================================
 
@@ -1044,7 +1043,7 @@ following code will generate 3 constructors:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_simple,indent=0]
 ----
 
 The first constructor is a no-arg constructor which allows the traditional map-style construction so long as
@@ -1084,49 +1083,49 @@ The `@TupleConstructor` AST transformation accepts several annotation attributes
 |excludes|Empty list|List of properties to exclude from tuple constructor generation|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_excludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_excludes,indent=0]
 ----
 |includes|Undefined list (indicates all fields)|List of fields to include in tuple constructor generation|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includes,indent=0]
 ----
 |includeProperties|True|Should properties be included in tuple constructor generation|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeProperties,indent=0]
 ----
 |includeFields|False|Should fields be included in tuple constructor generation, in addition to properties|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeFields,indent=0]
 ----
 |includeSuperProperties|True|Should properties from super classes be included in tuple constructor generation|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperProperties,indent=0]
 ----
 |includeSuperFields|False|Should fields from super classes be included in tuple constructor generation|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperFields,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_includeSuperFields,indent=0]
 ----
 |callSuper|False|Should super properties be called within a call to the parent constructor rather than set as properties|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_callSuper,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_callSuper,indent=0]
 ----
 |force|False|By default, the transformation will do nothing if a constructor is already defined. Setting this attribute to
 true, the constructor will be generated and it's your responsibility to ensure that no duplicate constructor is defined.|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_force,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_force,indent=0]
 ----
 |defaults|True|Indicates that default value processing is enabled for constructor parameters.
 Set to false to obtain exactly one constructor but with initial value support and named-arguments disabled. |
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_false,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_false,indent=0]
 ----
 |useSetters|False|By default, the transformation will directly set the backing field of each property
 from its corresponding constructor parameter. Setting this attribute to true, the constructor will instead call setters if
@@ -1134,27 +1133,27 @@ they exist. It's usually deemed bad style from within a constructor to call sett
 responsibility to avoid such bad style.|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_useSetters,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_useSetters,indent=0]
 ----
 |allNames|False|Should fields and/or properties with internal names be included within the constructor|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allNames,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allNames,indent=0]
 ----
 |allProperties|False|Should JavaBean properties be included within the constructor|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_allProperties,indent=0]
 ----
 |pre|empty|A closure containing statements to be inserted at the start of the generated constructor(s)|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_pre,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_pre,indent=0]
 ----
 |post|empty|A closure containing statements to be inserted at the end of the generated constructor(s)|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_post,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_post,indent=0]
 ----
 |=======================================================================
 
@@ -1164,14 +1163,14 @@ multiple tuple constructors to be created by using different customization optio
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_multiple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_multiple,indent=0]
 ----
 
 Similarly, here is another example using different options for `includes`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_multipleIncludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=tupleconstructor_example_defaults_multipleIncludes,indent=0]
 ----
 
 [[xform-MapConstructor]]
@@ -1183,14 +1182,14 @@ having the key with the name of the property. Usage is as shown in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=mapconstructor_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=mapconstructor_simple,indent=0]
 ----
 
 The generated constructor will be roughly like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=mapconstructor_equiv,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=mapconstructor_equiv,indent=0]
 ----
 
 [[xform-Canonical]]
@@ -1202,7 +1201,7 @@ annotations:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=canonical_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=canonical_simple,indent=0]
 ----
 
 A similar immutable class can be generated using the <<x...@Immutable>> meta-annotation instead.
@@ -1211,7 +1210,7 @@ it aggregates. See those annotations for more details.
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=canonical_example_excludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=canonical_example_excludes,indent=0]
 ----
 
 The `@Canonical` meta-annotation can be used in conjunction with an explicit use one or more of its
@@ -1219,7 +1218,7 @@ component annotations, like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=canonical_example_excludes,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=canonical_example_excludes,indent=0]
 ----
 
 Any applicable annotation attributes from `@Canonical` are passed along to the explicit annotation but
@@ -1233,7 +1232,7 @@ is in particular useful when overriding exception classes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_simple,indent=0]
 ----
 
 The `@InheritConstructor` AST transformation supports the following configuration options:
@@ -1244,12 +1243,12 @@ The `@InheritConstructor` AST transformation supports the following configuratio
 |constructorAnnotations|False|Whether to carry over annotations from the constructor during copying|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_constructor_annotations,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_constructor_annotations,indent=0]
 ----
 |parameterAnnotations|False|Whether to carry over annotations from the constructor parameters when copying the constructor|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_parameter_annotations,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=inheritconstructors_parameter_annotations,indent=0]
 ----
 |=======================================================================
 
@@ -1261,7 +1260,7 @@ written like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=oldstyle_category,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=oldstyle_category,indent=0]
 ----
 
 The `@Category` transformation lets you write the same using an instance-style class, rather than a static class style.
@@ -1270,7 +1269,7 @@ this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=newstyle_category,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=newstyle_category,indent=0]
 ----
 
 Note that the mixed in class can be referenced using `this` instead. It's also worth noting that using instance fields
@@ -1286,7 +1285,7 @@ form:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=indexedproperty_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=indexedproperty_simple,indent=0]
 ----
 
 [[xform-Lazy]]
@@ -1296,14 +1295,14 @@ The `@Lazy` AST transformation implements lazy initialization of fields. For exa
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=lazy_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=lazy_simple,indent=0]
 ----
 
 will produce the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=lazy_simple_generated,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=lazy_simple_generated,indent=0]
 ----
 
 The default value which is used to initialize the field is the default constructor of the declaration type. It is possible
@@ -1311,13 +1310,13 @@ to define a default value by using a closure on the right hand side of the prope
 example:
 
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=lazy_default,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=lazy_default,indent=0]
 ----
 
 In that case, the generated code looks like the following:
 
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=lazy_default_generated,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=lazy_default_generated,indent=0]
 ----
 
 If the field is declared volatile then initialization will be synchronized using the
@@ -1335,12 +1334,12 @@ The `@Newify` AST transformation is used to bring alternative syntaxes to constr
 * Using the `Python` style:
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=newify_python,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=newify_python,indent=0]
 ----
 * or using the `Ruby` style:
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=newify_ruby,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=newify_ruby,indent=0]
 ----
 The `Ruby` version can be disabled by setting the `auto` flag to `false`.
 
@@ -1353,7 +1352,7 @@ the `Person` class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple,indent=0]
 ----
 
 The generated class has the following properties:
@@ -1366,13 +1365,13 @@ The generated `compareTo` method will look like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_generated_compareTo,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_generated_compareTo,indent=0]
 ----
 As an example of the generated comparators, the `comparatorByFirst` comparator will have a `compare` method that looks like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_generated_comparatorByFirst,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_generated_comparatorByFirst,indent=0]
 ----
 
 The `Person` class can be used wherever a `Comparable` is expected and the generated comparators
@@ -1380,7 +1379,7 @@ wherever a `Comparator` is expected as shown by these examples:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_simple_usage,indent=0]
 ----
 
 Normally, all properties are used in the generated `compareTo` method in the priority order in which they are defined.
@@ -1390,21 +1389,21 @@ determine the priority of properties when comparing. To illustrate, consider the
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom,indent=0]
 ----
 
 It will have two comparator methods `comparatorByFirst` and `comparatorByBorn` and the generated `compareTo` method will look like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom_generated_compareTo,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom_generated_compareTo,indent=0]
 ----
 
 This `Person` class can be used as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_custom_usage,indent=0]
 ----
 
 The behavior of the `@Sortable` AST transformation can be further changed using the following additional parameters:
@@ -1415,17 +1414,17 @@ The behavior of the `@Sortable` AST transformation can be further changed using
 |allProperties|True|Should JavaBean properties (ordered after native properties) be used|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_allProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_allProperties,indent=0]
 ----
 |allNames|False|Should properties with "internal" names be used|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_allNames,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_allNames,indent=0]
 ----
 |includeSuperProperties|False|Should super properties also be used (ordered first)|
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_superProperties,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=sortable_example_superProperties,indent=0]
 ----
 |=======================================================================
 
@@ -1451,35 +1450,35 @@ To use the `SimpleStrategy`, annotate your Groovy class using the `@Builder` ann
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple,indent=0]
 ----
 
 Then, just call the setters in a chained fashion as shown here:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_usage,indent=0]
 ----
 
 For each property, a generated setter will be created which looks like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_generated_setter,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_generated_setter,indent=0]
 ----
 
 You can specify a prefix as shown in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_prefix,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_prefix,indent=0]
 ----
 
 And calling the chained setters would look like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_prefix_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_prefix_usage,indent=0]
 ----
 
 You can use the `SimpleStrategy` in conjunction with `@TupleConstructor`. If your `@Builder`
@@ -1495,7 +1494,7 @@ The annotation attributes `builderClassName`, `buildMethodName`, `builderMethodN
 NOTE: Groovy already has built-in building mechanisms. Don't rush to using `@Builder` if the built-in mechanisms meet your needs. Some examples:
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_alternatives,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_simple_alternatives,indent=0]
 ----
 
 .ExternalStrategy
@@ -1505,14 +1504,14 @@ Suppose you have the following class you would like a builder for:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_buildee,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_buildee,indent=0]
 ----
 
 you explicitly create and use your builder class as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_external,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_external,indent=0]
 ----
 
 Note that the (normally empty) builder class you provide will be filled in with appropriate setters and a build method.
@@ -1520,7 +1519,7 @@ The generated build method will look something like:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_generated_build,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_generated_build,indent=0]
 ----
 
 The class you are creating the builder for can be any Java or Groovy class following the normal JavaBean conventions,
@@ -1528,7 +1527,7 @@ e.g. a no-arg constructor and setters for the properties. Here is an example usi
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_java,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_java,indent=0]
 ----
 
 The generated builder can be customised using the `prefix`, `includes`, `excludes` and `buildMethodName` annotation attributes.
@@ -1536,7 +1535,7 @@ Here is an example illustrating various customisations:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_custom,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_external_custom,indent=0]
 ----
 
 The `builderMethodName` and `builderClassName` annotation attributes for `@Builder` aren't applicable for this strategy.
@@ -1551,7 +1550,7 @@ To use the `DefaultStrategy`, annotate your Groovy class using the `@Builder` an
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_default,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_default,indent=0]
 ----
 
 If you want, you can customize various aspects of the building process
@@ -1560,7 +1559,7 @@ some of which are used in the example here:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_default_custom,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_default_custom,indent=0]
 ----
 
 This strategy also supports annotating static methods and constructors. In this case, the static method or constructor
@@ -1572,7 +1571,7 @@ Here is an example highlighting method and constructor usage (and also illustrat
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_default_methods,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_default_methods,indent=0]
 ----
 
 The `forClass` annotation attribute is not supported for this strategy.
@@ -1582,7 +1581,7 @@ To use the `InitializerStrategy`, annotate your Groovy class using the `@Builder
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer,indent=0]
 ----
 
 Your class will be locked down to have a single public constructor taking a "fully set" initializer.
@@ -1590,7 +1589,7 @@ It will also have a factory method to create the initializer. These are used as
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer_usage,indent=0]
 ----
 
 Any attempt to use the initializer which doesn't involve setting all the properties (though order is not important) will result in
@@ -1602,7 +1601,7 @@ from `@Canonical` will be re-used for `@Builder`. Here is an example using `@Bui
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer_immutable,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=builder_initializer_immutable,indent=0]
 ----
 
 The annotation attribute `useSetters` can be used if you have a setter which you want called as part of the
@@ -1634,7 +1633,7 @@ has a superclass and a single interface as can be seen here:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default,indent=0]
 ----
 
 A `void close()` method from the
@@ -1646,14 +1645,14 @@ of the methods) using the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default_usage,indent=0]
 ----
 
 It is also worthwhile examining the equivalent generated code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default_equiv,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_default_equiv,indent=0]
 ----
 
 The second example illustrates the simplest exception case. Our class is annotated with `@AutoImplement`,
@@ -1662,7 +1661,7 @@ our "dummy" methods are called. Here is the class definition:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception,indent=0]
 ----
 
 We can use the class (and check the expected exception is thrown for one
@@ -1670,7 +1669,7 @@ of the methods) using the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception_usage,indent=0]
 ----
 
 It is also worthwhile examining the equivalent generated code where three void methods
@@ -1678,7 +1677,7 @@ have been provided all of which throw the supplied exception:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception_equiv,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exception_equiv,indent=0]
 ----
 
 The third example illustrates the exception case with a supplied message. Our class is annotated with `@AutoImplement`,
@@ -1687,7 +1686,7 @@ implements an interface, and has annotation attributes to indicate that an `Unsu
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg,indent=0]
 ----
 
 We can use the class (and check the expected exception is thrown and has the correct message
@@ -1695,7 +1694,7 @@ for one of the methods) using the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg_usage,indent=0]
 ----
 
 It is also worthwhile examining the equivalent generated code where three void methods
@@ -1703,7 +1702,7 @@ have been provided all of which throw the supplied exception:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg_equiv,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_exceptionmsg_equiv,indent=0]
 ----
 
 The fourth example illustrates the case of user supplied code. Our class is annotated with `@AutoImplement`,
@@ -1712,7 +1711,7 @@ supplied code for any supplied methods. Here is the class definition:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code,indent=0]
 ----
 
 We can use the class (and check the expected exception is thrown and has a message of the expected form)
@@ -1720,14 +1719,14 @@ using the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code_usage,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code_usage,indent=0]
 ----
 
 It is also worthwhile examining the equivalent generated code where the `next` method has been supplied:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code_equiv,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=autoimplement_code_equiv,indent=0]
 ----
 
 [[xform-NullCheck]]
@@ -1741,7 +1740,7 @@ in which case it will apply to all methods/constructors.
 
 [source,groovy]
 ----
-include::{includedir}/../test/CodeGenerationASTTransformsTest.groovy[tags=nullcheck,indent=0]
+include::{projectdir}/src/spec/test/CodeGenerationASTTransformsTest.groovy[tags=nullcheck,indent=0]
 ----
 
 ==== Class design annotations
@@ -1754,7 +1753,7 @@ singleton, ...) by using a declarative style.
 
 `@BaseScript` is used within scripts to indicate that the script should
 extend fron a custom script base class rather than `groovy.lang.Script`.
-See the documentation for <<core-domain-specific-languages.adoc#dsl-basescript,domain specific languages>> for further details.
+See the documentation for <<dsl-basescript,domain specific languages>> for further details.
 
 [[xform-Delegate]]
 ===== `@groovy.lang.Delegate`
@@ -1763,7 +1762,7 @@ The `@Delegate` AST transformation aims at implementing the delegation design pa
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegating_class,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegating_class,indent=0]
 ----
 
 The `when` property is annotated with `@Delegate`, meaning that the `Event` class will delegate calls to `Date` methods
@@ -1771,14 +1770,14 @@ to the `when` property. In this case, the generated code looks like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegating_class_generated,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegating_class_generated,indent=0]
 ----
 
 Then you can call the `before` method, for example, directly on the `Event` class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegation_assert,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegation_assert,indent=0]
 ----
 
 Instead of annotating a property (or field), you can also annotate a method.
@@ -1788,14 +1787,14 @@ accessed in a round-robin fashion:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_method,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_method,indent=0]
 ----
 
 Here is an example usage of that class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_method_usage,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_method_usage,indent=0]
 ----
 
 Using a standard list in this round-robin fashion would violate many expected properties of lists, so
@@ -1809,54 +1808,54 @@ The behavior of the `@Delegate` AST transformation can be changed using the foll
 |interfaces|True|Should the interfaces implemented by the field be implemented by the class too|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_interfaces,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_interfaces,indent=0]
 ----
 |deprecated|false|If true, also delegates methods annotated with @Deprecated|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_deprecated_header,indent=0]
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_deprecated_footer,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_deprecated_header,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_deprecated_footer,indent=0]
 ----
 |methodAnnotations|False|Whether to carry over annotations from the methods of the delegate to your delegating method.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_annotations,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_annotations,indent=0]
 ----
 |parameterAnnotations|False|Whether to carry over annotations from the method parameters of the delegate to your delegating method.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_parameter_annotations,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_parameter_annotations,indent=0]
 ----
 |excludes|Empty array|A list of methods to be excluded from delegation. For more fine-grained control, see also `excludeTypes`.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludes_header,indent=0]
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludes_footer,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludes_header,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludes_footer,indent=0]
 ----
 |includes|Undefined marker array (indicates all methods)|A list of methods to be included in delegation. For more
 fine-grained
 control, see also `includeTypes`.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includes_header,indent=0]
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includes_footer,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includes_header,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includes_footer,indent=0]
 ----
 |excludeTypes|Empty array|A list of interfaces containing method signatures to be excluded from delegation|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludeTypes,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_excludeTypes,indent=0]
 ----
 |includeTypes|Undefined marker array (indicates no list be default)|A list of interfaces containing method signatures to
  be included in delegation|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includeTypes_header,indent=0]
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includeTypes_footer,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includeTypes_header,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_includeTypes_footer,indent=0]
 ----
 |allNames|False|Should the delegate pattern be also applied to methods with internal names|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_allNames,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=delegate_example_allNames,indent=0]
 ----
 |=======================================================================
 
@@ -1883,7 +1882,7 @@ To use the meta-annotation, all you have to do is annotate the class like in the
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=immutable_simple,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=immutable_simple,indent=0]
 ----
 
 One of the requirements for immutable classes is that there is no way to modify any state information within the class.
@@ -1918,7 +1917,7 @@ The following annotation attribute is supported:
 |copyWith|false|A boolean whether to generate a `copyWith( Map )` method.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_copyWith,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_copyWith,indent=0]
 ----
 |=======================================================================
 
@@ -1937,7 +1936,7 @@ This annotation allows you to specify a custom visibility for a construct genera
 It is ignored by the main Groovy compiler but is referenced by other transformations
 like `@TupleConstructor`, `@MapConstructor`, and `@NamedVariant`.
 
-[[xform-ImmutableOptions]]
+[[xform-ImumtableOptions]]
 ===== `@groovy.transform.ImmutableOptions`
 
 Groovy's immutability support relies on a predefined list of known immutable classes (like `java.net.URI` or `java.lang.String`
@@ -1950,12 +1949,12 @@ thanks to the following annotation attributes of the `@ImmutableOptions` annotat
 |knownImmutableClasses|Empty list|A list of classes which are deemed immutable.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_knownimmutableclasses,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_knownimmutableclasses,indent=0]
 ----
 |knownImmutables|Empty list|A list of property names which are deemed immutable.|
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_knownimmutables,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=immutable_example_knownimmutables,indent=0]
 ----
 |=======================================================================
 
@@ -1978,7 +1977,7 @@ to be cached just by annotating the method with `@Memoized`. Let's imagine the f
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation,indent=0]
 ----
 
 This emulates a long computation, based on the actual parameters of the method. Without `@Memoized`, each method call
@@ -1986,14 +1985,14 @@ would take several seconds plus it would return a random result:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation_asserts,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation_asserts,indent=0]
 ----
 
 Adding `@Memoized` changes the semantics of the method by adding caching, based on the parameters:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation_cached,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=memoized_long_computation_cached,indent=0]
 ----
 
 The size of the cache can be configured using two optional parameters:
@@ -2015,7 +2014,7 @@ Below is an example of use when calculating factorial:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=tailrecursive,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=tailrecursive,indent=0]
 ----
 
 Currently, the annotation will only work for self-recursive method calls, i.e. a single recursive call to the exact same method again.
@@ -2034,7 +2033,7 @@ double checked locking.
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=singleton_simple,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=singleton_simple,indent=0]
 ----
 
 By default, the singleton is created eagerly when the class is initialized and available through the `instance` property.
@@ -2042,14 +2041,14 @@ It is possible to change the name of the singleton using the `property` paramete
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=singleton_example_property,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=singleton_example_property,indent=0]
 ----
 
 And it is also possible to make initialization lazy using the `lazy` parameter:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassDesignASTTransformsTest.groovy[tags=singleton_example_lazy,indent=0]
+include::{projectdir}/src/spec/test/ClassDesignASTTransformsTest.groovy[tags=singleton_example_lazy,indent=0]
 ----
 
 In this example, we also set the `strict` parameter to false, which allows us to define our own constructor.
@@ -2082,14 +2081,14 @@ The first logging AST transformation available is the `@Log` annotation which re
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log_spec,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log_spec,indent=0]
 ----
 
 is equivalent to writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log_equiv,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log_equiv,indent=0]
 ----
 
 [[xform-Commons]]
@@ -2100,14 +2099,14 @@ Groovy supports the http://commons.apache.org/proper/commons-logging/[Apache Com
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=commons_spec,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=commons_spec,indent=0]
 ----
 
 is equivalent to writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=commons_equiv,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=commons_equiv,indent=0]
 ----
 
 [[xform-Log4j]]
@@ -2118,14 +2117,14 @@ Groovy supports the http://logging.apache.org/log4j/1.2/[Apache Log4j 1.x] frame
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log4j_spec,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log4j_spec,indent=0]
 ----
 
 is equivalent to writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log4j_equiv,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log4j_equiv,indent=0]
 ----
 
 [[xform-Log4j2]]
@@ -2136,14 +2135,14 @@ Groovy supports the http://logging.apache.org/log4j/2.x/[Apache Log4j 2.x] frame
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log4j2_spec,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log4j2_spec,indent=0]
 ----
 
 is equivalent to writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=log4j2_equiv,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=log4j2_equiv,indent=0]
 ----
 
 [[xform-Slf4j]]
@@ -2154,14 +2153,14 @@ Groovy supports the http://www.slf4j.org/[Simple Logging Facade for Java (SLF4J)
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=slf4j_spec,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=slf4j_spec,indent=0]
 ----
 
 is equivalent to writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/LogImprovementsASTTransformsTest.groovy[tags=slf4j_equiv,indent=0]
+include::{projectdir}/src/spec/test/LogImprovementsASTTransformsTest.groovy[tags=slf4j_equiv,indent=0]
 ----
 
 ==== Declarative concurrency
@@ -2177,14 +2176,14 @@ objects for safer concurrency. It can be applied on any method or static method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized,indent=0]
 ----
 
 Writing this is equivalent to creating a lock object and wrapping the whole method into a synchronized block:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized_equiv,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized_equiv,indent=0]
 ----
 
 By default, `@Synchronized` creates a field named `$lock` (or `$LOCK` for a static method) but you can make it use any
@@ -2192,7 +2191,7 @@ field you want by specifying the value attribute, like in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized_customlock,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_synchronized_customlock,indent=0]
 ----
 
 [[xform-WithReadLock]]
@@ -2205,14 +2204,14 @@ can be added to a method or a static method. It will transparently create a `$re
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock,indent=0]
 ----
 
 is equivalent to this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock_equiv,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock_equiv,indent=0]
 ----
 
 Both `@WithReadLock` and `@WithWriteLock` support specifying an alternative lock object. In that case, the referenced
@@ -2220,7 +2219,7 @@ Both `@WithReadLock` and `@WithWriteLock` support specifying an alternative lock
 
 [source,groovy]
 ----
-include::{includedir}/../test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock_alter,indent=0]
+include::{projectdir}/src/spec/test/DeclarativeConcurrencyASTTransformsTest.groovy[tags=example_rwlock_alter,indent=0]
 ----
 
 For details
@@ -2249,14 +2248,14 @@ For example, the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoclone,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoclone,indent=0]
 ----
 
 is equivalent to this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoclone_equiv,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoclone_equiv,indent=0]
 ----
 
 Note that the String properties aren't explicitly handled because Strings are immutable and the `clone()` method from `Object` will copy the String references. The same would apply to primitive fields and most of the concrete subclasses of `java.lang.Number`.
@@ -2270,12 +2269,12 @@ In addition to cloning styles, `@AutoClone` supports multiple options:
 See gapi:groovy.transform.AutoClone#excludes[] for details|
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoclone_excludes,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoclone_excludes,indent=0]
 ----
 |includeFields|false|By default, only properties are cloned. Setting this flag to true will also clone fields.|
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoclone_includeFields,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoclone_includeFields,indent=0]
 ----
 |=======================================================================
 
@@ -2288,14 +2287,14 @@ code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoext,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoext,indent=0]
 ----
 
 will be converted into:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoext_equiv,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoext_equiv,indent=0]
 ----
 
 The `@AutoExternalize` annotation supports two parameters which will let you slightly customize its behavior:
@@ -2307,12 +2306,12 @@ The `@AutoExternalize` annotation supports two parameters which will let you sli
 See gapi:groovy.transform.AutoExternalize#excludes[] for details|
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoext_excludes,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoext_excludes,indent=0]
 ----
 |includeFields|false|By default, only properties are externalized. Setting this flag to true will also clone fields.|
 [source,groovy]
 ----
-include::{includedir}/../test/CloningASTTransformsTest.groovy[tags=example_autoext_includeFields,indent=0]
+include::{projectdir}/src/spec/test/CloningASTTransformsTest.groovy[tags=example_autoext_includeFields,indent=0]
 ----
 |=======================================================================
 
@@ -2344,7 +2343,7 @@ Let's imagine the following user script:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_infiniteloop,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_infiniteloop,indent=0]
 ----
 
 This is an obvious infinite loop. If this code executes in its own thread, interrupting wouldn't help: if you `join` on
@@ -2355,7 +2354,7 @@ One possibility to work around this is to set up your shell this way:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_shell_setup,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_shell_setup,indent=0]
 ----
 
 The shell is then configured to automatically apply the `@ThreadInterrupt` AST transformations on all scripts. This allows
@@ -2363,14 +2362,14 @@ you to execute user scripts this way:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_control,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_control,indent=0]
 ----
 
 The transformation automatically modified user code like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_infiniteloop_equiv,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_infiniteloop_equiv,indent=0]
 ----
 
 The check which is introduced inside the loop guarantees that if the `interrupt` flag is set on the current thread, an
@@ -2384,7 +2383,7 @@ exception will be thrown, interrupting the execution of the thread.
 |thrown|`java.lang.InterruptedException`|Specifies the type of exception which is thrown if the thread is interrupted.|
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_thrown,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=threadinterrupt_thrown,indent=0]
 ----
 |checkOnMethodStart|true|Should an interruption check be inserted at the beginning of each method body. See gapi:groovy.transform.ThreadInterrupt[] for details.|
 [source,groovy]
@@ -2422,7 +2421,7 @@ Imagine the following user code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_fib,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_fib,indent=0]
 ----
 
 The implementation of the famous Fibonacci number computation here is far from optimized. If it is called with a high `n` value, it can take minutes to answer. With `@TimedInterrupt`, you can
@@ -2430,7 +2429,7 @@ choose how long a script is allowed to run. The following setup code will allow
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_shell_setup,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_shell_setup,indent=0]
 ----
 
 This code is equivalent to annotating a class with `@TimedInterrupt` like this:
@@ -2453,17 +2452,17 @@ class MyClass {
 |value|Long.MAX_VALUE|Used in combination with `unit` to specify after how long execution times out.|
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_duration,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_duration,indent=0]
 ----
 |unit|TimeUnit.SECONDS|Used in combination with `value` to specify after how long execution times out.|
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_duration,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_duration,indent=0]
 ----
 |thrown|`java.util.concurrent.TimeoutException`|Specifies the type of exception which is thrown if timeout is reached.|
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_thrown,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=timedinterrupt_thrown,indent=0]
 ----
 |checkOnMethodStart|true|Should an interruption check be inserted at the beginning of each method body. See gapi:groovy.transform.TimedInterrupt[] for details.|
 [source,groovy]
@@ -2499,21 +2498,21 @@ to check a quota manager and interrupt automatically the script:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt,indent=0]
 ----
 
 The quota checking is very basic here, but it can be any code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_quotaclass,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_quotaclass,indent=0]
 ----
 
 We can make sure `@ConditionalInterrupt` works properly using this test code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_assert,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_assert,indent=0]
 ----
 
 Of course, in practice, it is unlikely that `@ConditionalInterrupt` will be itself added by hand on user code. It can be injected in a similar manner as the example shown in the
@@ -2521,7 +2520,7 @@ Of course, in practice, it is unlikely that `@ConditionalInterrupt` will be itse
 
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_injected,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_injected,indent=0]
 ----
 
 `@ConditionalInterrupt` supports multiple options that will let you further customize the behavior of the transformation:
@@ -2537,7 +2536,7 @@ include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=condit
 |thrown|`java.lang.InterruptedException`|Specifies the type of exception which is thrown if execution should be aborted.|
 [source,groovy]
 ----
-include::{includedir}/../test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_thrown,indent=0]
+include::{projectdir}/src/spec/test/SaferScriptingASTTransformsTest.groovy[tags=conditionalinterrupt_thrown,indent=0]
 ----
 |checkOnMethodStart|true|Should an interruption check be inserted at the beginning of each method body. See gapi:groovy.transform.ConditionalInterrupt[] for details.|
 [source,groovy]
@@ -2576,7 +2575,7 @@ scripts. The following example will for example fail at runtime:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=field_missing_property,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=field_missing_property,indent=0]
 ----
 
 The error that is thrown may be difficult to interpret: +groovy.lang.MissingPropertyException: No such property: x+. The reason is that scripts are compiled
@@ -2585,7 +2584,7 @@ equivalent to this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=field_missing_property_equiv,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=field_missing_property_equiv,indent=0]
 ----
 
 So `def x` is effectively interpreted as a local variable, outside of the scope of the `line` method. The `@Field` AST transformation aims at fixing this
@@ -2593,14 +2592,14 @@ by changing the scope of the variable to a field of the enclosing script:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=field_fixed,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=field_fixed,indent=0]
 ----
 
 The resulting, equivalent, code is now:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=field_fixed_equiv,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=field_fixed_equiv,indent=0]
 ----
 
 [[xform-PackageScope]]
@@ -2610,14 +2609,14 @@ By default, Groovy visibility rules imply that if you create a field without spe
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property,indent=0]
 ----
 
 Should you want to create a package private field instead of a property (private field+getter/setter), then annotate your field with `@PackageScope`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property_javalike,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property_javalike,indent=0]
 ----
 
 The `@PackageScope` annotation can also be used for classes, methods and constructors. In addition, by specifying a list
@@ -2627,7 +2626,7 @@ to fields within a class use the following annotation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property_usingtarget,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=packagescope_property_usingtarget,indent=0]
 ----
 
 The `@PackageScope` annotation is seldom used as part of normal Groovy conventions but is sometimes useful
@@ -2655,7 +2654,7 @@ The following example illustrates applying the annotation at the class level:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=autofinal_class,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=autofinal_class,indent=0]
 ----
 
 In this example, the two parameters for the constructor and the single parameter for
@@ -2666,7 +2665,7 @@ The following example illustrates applying the annotation at the method level:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CompilerDirectivesASTTransformsTest.groovy[tags=autofinal_method,indent=0]
+include::{projectdir}/src/spec/test/CompilerDirectivesASTTransformsTest.groovy[tags=autofinal_method,indent=0]
 ----
 
 Here, the `add` method will have final parameters but the `mult` method will remain unchanged.
@@ -2702,7 +2701,7 @@ using <<xform-TypeChecked,type checking>> or <<xform-CompileStatic, static compi
 ===== `@groovy.transform.SelfType`
 
 `@SelfType` is not an AST transformation but rather a marker interface used
-with traits. See the <<core-object-orientation.adoc#traits-selftype,traits documentation>> for further details.
+with traits. See the <<core-traits#traits-selftype,traits documentation>> for further details.
 
 ==== Swing patterns
 
@@ -2714,21 +2713,21 @@ The `@Bindable` annotation can be placed on a property or a class. To convert al
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=bindable_on_class,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=bindable_on_class,indent=0]
 ----
 
 This is equivalent to writing this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=bindable_on_class_equiv,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=bindable_on_class_equiv,indent=0]
 ----
 
 `@Bindable` therefore removes a lot of boilerplate from your class, dramatically increasing readability. If the annotation is put on a single property, only that property is bound:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=bindable_single_property,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=bindable_single_property,indent=0]
 ----
 
 [[xform-ListenerList]]
@@ -2738,14 +2737,14 @@ The `@ListenerList` AST transformation generates code for adding, removing and g
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=listenerlist_simple,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=listenerlist_simple,indent=0]
 ----
 
 The transform will generate the appropriate add/remove methods based on the generic type of the list. In addition, it will also create `fireXXX` methods based on the public methods declared on the class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=listenerlist_simple_equiv,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=listenerlist_simple_equiv,indent=0]
 ----
 
 `@Bindable` supports multiple options that will let you further customize the behavior of the transformation:
@@ -2756,12 +2755,12 @@ include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=listenerlist_si
 |name|Generic type name|By default, the suffix which will be appended to add/remove/... methods is the simple class name of the generic type of the list.|
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=listenerlist_name,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=listenerlist_name,indent=0]
 ----
 |synchronize|false|If set to true, generated methods will be synchronized|
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=listenerlist_synchronized,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=listenerlist_synchronized,indent=0]
 ----
 |=======================================================================
 
@@ -2773,21 +2772,21 @@ can be placed on a class, meaning that all properties will be converted to const
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=vetoable_on_class,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=vetoable_on_class,indent=0]
 ----
 
 is equivalent to writing this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=vetoable_on_class_equiv,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=vetoable_on_class_equiv,indent=0]
 ----
 
 If the annotation is put on a single property, only that property is made vetoable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SwingASTTransformsTest.groovy[tags=vetoable_single_property,indent=0]
+include::{projectdir}/src/spec/test/SwingASTTransformsTest.groovy[tags=vetoable_single_property,indent=0]
 ----
 
 ==== Test assistance
@@ -2799,7 +2798,7 @@ that the test fails. Marking it with `@NotYetImplemented` will inverse the resul
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=notyetimplemented,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=notyetimplemented,indent=0]
 ----
 
 Another advantage of using this technique is that you can write test cases for bugs before knowing how to fix them. If some time in the future, a modification in the code fixes a bug by side effect,
@@ -2823,7 +2822,7 @@ For example, you can annotate a class node like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=asttest_basic,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=asttest_basic,indent=0]
 ----
 <1> we're checking the state of the Abstract Syntax Tree after the CONVERSION phase
 <2> node refers to the AST node which is annotated by @ASTTest
@@ -2835,7 +2834,7 @@ transform runs, which can be found in gapi:org.codehaus.groovy.transform.Package
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=asttest_packagescope,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=asttest_packagescope,indent=0]
 ----
 
 [[asttest-lookup]]
@@ -2854,7 +2853,7 @@ Imagine, for example, that you want to test the declared type of a for loop vari
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=asttest_forloop,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=asttest_forloop,indent=0]
 ----
 
 `@ASTTest` also exposes those variables inside the test closure:
@@ -2871,14 +2870,14 @@ As an example, here is how you could dump the list of AST transformations regist
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=dump_ast_xforms,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=dump_ast_xforms,indent=0]
 ----
 
 And here is how you can memorize variables for testing between two phases:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TestingASTTransformsTest.groovy[tags=memorize_in_binding,indent=0]
+include::{projectdir}/src/spec/test/TestingASTTransformsTest.groovy[tags=memorize_in_binding,indent=0]
 ----
 <1> if the current compile phase is instruction selection
 <2> then we want to make sure `toString` was added at `CANONICALIZATION`
@@ -2962,7 +2961,7 @@ actually print "Hello World" along with a start and stop message:
 [source,groovy]
 .Poor man's aspect oriented programming
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example,indent=0]
 ----
 
 A local AST transformation is an easy way to do this. It requires two things:
@@ -2988,7 +2987,7 @@ The local transformation annotation is the simple part. Here is the
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_ann,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_ann,indent=0]
 ----
 
 The annotation retention can be `SOURCE` because you won’t need the annotation
@@ -3012,7 +3011,7 @@ stop message for `@WithLogging`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_xform,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_xform,indent=0]
 ----
 <1> even if not mandatory, if you write an AST transformation in Groovy, it is highly recommended to use `CompileStatic`
 because it will improve performance of the compiler.
@@ -3046,7 +3045,7 @@ In the end:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example,indent=0]
 ----
 
 Produces:
@@ -3072,13 +3071,13 @@ Global AST transformation are similar to local one with a major difference: they
 they are applied _globally_, that is to say on each class being compiled. It is therefore very important to limit their
 use to last resort, because it can have a significant impact on the compiler performance.
 
-Following the example of the <<transforms-local,local AST transformation>>, imagine that we would like to trace all
+Following the example of the <<transform-local,local AST transformation>>, imagine that we would like to trace all
 methods, and not only those which are annotated with `@WithLogging`. Basically, we need this code to behave the same
 as the one annotated with `@WithLogging` before:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example_global,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_example_global,indent=0]
 ----
 
 To make this work, there are two steps:
@@ -3091,7 +3090,7 @@ The descriptor file is required and must be found on classpath. It will contain
 [source,groovy]
 .META-INF/services/org.codehaus.groovy.transform.ASTTransformation
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=xform_descriptor_file,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=xform_descriptor_file,indent=0]
 ----
 
 The code for the transformation looks similar to the local case, but instead of using the `ASTNode[]` parameter, we need
@@ -3100,7 +3099,7 @@ to use the `SourceUnit` instead:
 [source,groovy]
 .gep/WithLoggingASTTransformation.groovy
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_xform_global,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=withlogging_xform_global,indent=0]
 ----
 <1> even if not mandatory, if you write an AST transformation in Groovy, it is highly recommended to use `CompileStatic`
 because it will improve performance of the compiler.
@@ -3136,7 +3135,7 @@ arguments into their uppercase version. For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=shout_example,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=shout_example,indent=0]
 ----
 
 should print:
@@ -3149,7 +3148,7 @@ Then the code for the transformation can use the `ClassCodeExpressionTransformer
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=shout_xform,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=shout_xform,indent=0]
 ----
 <1> Internally the transformation creates a `ClassCodeExpressionTransformer`
 <2> The transformer needs to return the source unit
@@ -3190,14 +3189,14 @@ straight forward:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroStatementTest.groovy[tags=addmethodannotation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroStatementTest.groovy[tags=addmethodannotation,indent=0]
 ----
 
 What would the AST transformation look like without the use of a macro ? Something like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroStatementTest.groovy[tags=addmethodtransformationwithoutmacro,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroStatementTest.groovy[tags=addmethodtransformationwithoutmacro,indent=0]
 ----
 
 <1> Create a return statement
@@ -3210,7 +3209,7 @@ previous code simplifies with the use of macros.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroStatementTest.groovy[tags=basicWithMacro,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroStatementTest.groovy[tags=basicWithMacro,indent=0]
 ----
 
 <1> Much simpler. You wanted to add a return statement that returned "42" and that's exactly what you can read inside
@@ -3235,7 +3234,7 @@ should use any of the `macro` invocations with a boolean parameter:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroExpressionTest.groovy[tags=addgettwotransformation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroExpressionTest.groovy[tags=addgettwotransformation,indent=0]
 ----
 
 <1> We're telling macro not to wrap the expression in a statement, we're only interested in the expression
@@ -3254,14 +3253,14 @@ add a method returning the MD5 value of that field.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroVariableSubstitutionTest.groovy[tags=md5annotation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroVariableSubstitutionTest.groovy[tags=md5annotation,indent=0]
 ----
 
 And the transformation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroVariableSubstitutionTest.groovy[tags=md5transformation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroVariableSubstitutionTest.groovy[tags=md5transformation,indent=0]
 ----
 
 <1> We need a reference to a variable expression
@@ -3287,14 +3286,14 @@ is the marker annotation.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroClassTest.groovy[tags=statisticsannotation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroClassTest.groovy[tags=statisticsannotation,indent=0]
 ----
 
 And the AST transformation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/MacroClassTest.groovy[tags=statisticstransformation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/MacroClassTest.groovy[tags=statisticstransformation,indent=0]
 ----
 
 <1> Creating a template class
@@ -3383,14 +3382,14 @@ instead of writing this in a test case:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=breakpoint_missed,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=breakpoint_missed,indent=0]
 ----
 
 You should write:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTXFormSpecTest.groovy[tags=breakpoint_hit,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTXFormSpecTest.groovy[tags=breakpoint_hit,indent=0]
 ----
 
 The difference is that when you use `assertScript`, the code in the `assertScript` block is compiled *when the
@@ -3413,7 +3412,7 @@ First we create the `@Joking` annotation that only can be applied to methods:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingannotation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingannotation,indent=0]
 ----
 
 Then the transformation, that only applies an instance of `org.codehaus.groovy.ast.ClassCodeExpressionTransformer`
@@ -3421,7 +3420,7 @@ to all the expressions within the method code block.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingtransformation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingtransformation,indent=0]
 ----
 <1> Get the method's code statement and apply the expression transformer
 
@@ -3430,7 +3429,7 @@ the expression `1 + 1`.
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingexpressiontransformer,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingexpressiontransformer,indent=0]
 ----
 <1> Builds the expression used as reference pattern
 <2> Checks the current expression evaluated matches the reference expression
@@ -3440,7 +3439,7 @@ Then you could test the implementation as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingexample,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherFilteringTest.groovy[tags=jokingexample,indent=0]
 ----
 
 **Unit testing AST transforms**
@@ -3453,7 +3452,7 @@ The following transformation adds a new method `giveMeTwo` to an annotated class
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherTestingTest.groovy[tags=twiceasttransformation,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherTestingTest.groovy[tags=twiceasttransformation,indent=0]
 ----
 <1> Adding the method to the annotated class
 <2> Building a binary expression. The binary expression uses the same variable expression in both
@@ -3466,7 +3465,7 @@ the construction of the binary expression is done properly:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherTestingTest.groovy[tags=testexpression,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherTestingTest.groovy[tags=testexpression,indent=0]
 ----
 <1> Using ASTMatcher as a category
 <2> Build a template node
@@ -3478,7 +3477,7 @@ Of course you can/should always check the actual execution:
 
 [source,groovy]
 ----
-include::{includedir}/../test/metaprogramming/ASTMatcherTestingTest.groovy[tags=executiontesting,indent=0]
+include::{projectdir}/src/spec/test/metaprogramming/ASTMatcherTestingTest.groovy[tags=executiontesting,indent=0]
 ----
 
 ===== ASTTest
diff --git a/src/spec/doc/core-object-orientation.adoc b/src/spec/doc/core-object-orientation.adoc
index 356b8d5..d858b8b 100644
--- a/src/spec/doc/core-object-orientation.adoc
+++ b/src/spec/doc/core-object-orientation.adoc
@@ -71,7 +71,7 @@ Here's an example using `int`
 
 [source,groovy]
 ----
-include::{includedir}/../test/PrimitiveTest.groovy[tags=primitive_references,indent=0]
+include::{projectdir}/src/spec/test/PrimitiveTest.groovy[tags=primitive_references,indent=0]
 ----
 
 Now you may be concerned that this means every time you use a mathematical operator on a reference to a primitive
@@ -101,7 +101,7 @@ The following code presents an example class.
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=class_definition,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=class_definition,indent=0]
 ----
 <1> class beginning, with the name `Person`
 <2> string field and property named `name`
@@ -114,7 +114,7 @@ Normal classes refer to classes which are top level and concrete. This means the
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=class_instantiation,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=class_instantiation,indent=0]
 ----
 
 
@@ -124,7 +124,7 @@ Inner classes are defined within another classes. The enclosing class can use th
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=inner_class,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=inner_class,indent=0]
 ----
 <1> the inner class is instantiated and its method gets called
 <2> inner class definition, inside its enclosing class
@@ -140,7 +140,7 @@ In several cases, inner classes are implementation of interfaces whose methods a
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=inner_class2,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=inner_class2,indent=0]
 ----
 
 Note that the class `Inner2` is defined only to provide an implementation of the method `run` to class `Outer2`. Anonymous inner classes help to eliminate verbosity in this case.
@@ -149,7 +149,7 @@ Since Groovy 3.0.0, Java syntax for non-static inner class instantiation is now
 
 [source,groovy]
 --------------------------------------
-include::{includedir}/../test/ClassTest.groovy[tags=inner_instantiation,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=inner_instantiation,indent=0]
 --------------------------------------
 
 ===== Anonymous inner class
@@ -158,7 +158,7 @@ The last example of inner class can be simplified with an anonymous inner class.
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=anonymous_inner_class,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=anonymous_inner_class,indent=0]
 ----
 <1> comparing with the last example of previous section, the `new Inner2()` was replaced by `new Runnable()` along with all its implementation
 <2> the method `start` is invoked normally
@@ -172,7 +172,7 @@ Abstract classes represent generic concepts, thus, they cannot be instantiated,
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=abstract_class,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=abstract_class,indent=0]
 ----
 <1> abstract classes must be declared with `abstract` keyword
 <2> abstract methods must also be declared with `abstract` keyword
@@ -186,7 +186,7 @@ to be implemented, but does not define the methods implementation.
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=interface_def_1,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=interface_def_1,indent=0]
 ----
 <1> an interface needs to be declared using the `interface` keyword
 <2> an interface only defines method signatures
@@ -195,7 +195,7 @@ Methods of an interface are always *public*. It is an error to use `protected` o
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=protected_forbidden,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=protected_forbidden,indent=0]
 ----
 <1> Using `protected` is a compile-time error
 
@@ -204,7 +204,7 @@ does:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=class_implements,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=class_implements,indent=0]
 ----
 <1> The `SystemGreeter` declares the `Greeter` interface using the `implements` keyword
 <2> Then implements the required `greet` method
@@ -214,7 +214,7 @@ An interface can extend another interface:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=extended_interface,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=extended_interface,indent=0]
 ----
 <1> the `ExtendedGreeter` interface extends the `Greeter` interface using the `extends` keyword
 
@@ -224,7 +224,7 @@ interfaces:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=no_structural_interface,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=no_structural_interface,indent=0]
 ----
 
 In other words, Groovy does not define structural typing. It is however possible to make an instance of an object
@@ -232,7 +232,7 @@ implement an interface at runtime, using the `as` coercion operator:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=interface_coercion,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=interface_coercion,indent=0]
 ----
 <1> create an instance of `DefaultGreeter` that does not implement the interface
 <2> coerce the instance into a `Greeter` at runtime
@@ -274,7 +274,7 @@ keyword and by statically typing the variable.
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=constructor_positional_parameters,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=constructor_positional_parameters,indent=0]
 ----
 <1> Constructor declaration
 <2> Constructor invocation, classic Java way
@@ -291,7 +291,7 @@ constructor may also be added using the gapi:groovy.transform.MapConstructor[] a
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=constructor_named_parameters,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=constructor_named_parameters,indent=0]
 ----
 <1> No constructor declared
 <2> No parameters given in the instantiation
@@ -329,7 +329,7 @@ Methods in Groovy always return some value. If no `return` statement is provided
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=method_definition ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=method_definition ,indent=0]
 ----
 <1> Method with no return type declared and no parameter
 <2> Method with explicit return type and no parameter
@@ -345,7 +345,7 @@ If the method has just a single Map argument, all supplied parameters must be na
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=named_arguments ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=named_arguments ,indent=0]
 ----
 
 ===== Mixing named and positional parameters
@@ -359,7 +359,7 @@ the first parameter automatically.
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=named_arguments_with_additional_arguments ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=named_arguments_with_additional_arguments ,indent=0]
 ----
 <1> Method call with additional `number` argument of `Integer` type
 <2> Method call with changed order of arguments
@@ -370,7 +370,7 @@ Failure to do so will lead to `groovy.lang.MissingMethodException`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=failed_named_arguments_with_additional_arguments ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=failed_named_arguments_with_additional_arguments ,indent=0]
 ----
 <1> Method call throws `groovy.lang.MissingMethodException: No signature of method: foo() is applicable for argument types: (LinkedHashMap, Integer) values: [[name:Marie, age:1], 23]`, because the named argument `Map` parameter is not defined as the first argument
 
@@ -378,7 +378,7 @@ Above exception can be avoided if we replace named arguments with an explicit `M
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=explicit_named_arguments_with_additional_arguments ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=explicit_named_arguments_with_additional_arguments ,indent=0]
 ----
 <1> Explicit `Map` argument in place of named arguments makes invocation valid
 
@@ -391,7 +391,7 @@ Default arguments make parameters optional. If the argument is not supplied, the
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=default_arguments ,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=default_arguments ,indent=0]
 ----
 
 Note that no mandatory parameter can be defined after a default parameter is present, only other default parameters.
@@ -403,7 +403,7 @@ Here `foo` supports `n` arguments by default, but also an unspecified number of
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=varargs_example,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=varargs_example,indent=0]
 ----
 
 This example defines a method `foo`, that can take any number of arguments, including no arguments at all.
@@ -412,21 +412,21 @@ That means any method with an array as last parameter is seen by Groovy as a met
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=varargs_array_notation,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=varargs_array_notation,indent=0]
 ----
 
 If a method with varargs is called with `null` as the vararg parameter, then the argument will be `null` and not an array of length one with `null` as the only element.
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=varargs_null_parameter,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=varargs_null_parameter,indent=0]
 ----
 
 If a varargs method is called with an array as an argument, then the argument will be that array instead of an array of length one containing the given array as the only element.
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=varargs_array_parameter,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=varargs_array_parameter,indent=0]
 ----
 
 Another important point are varargs in combination with method overloading. In case of method overloading Groovy will select the most specific method.
@@ -434,7 +434,7 @@ For example if a method `foo` takes a varargs argument of type `T` and another m
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=varargs_method_overloading,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=varargs_method_overloading,indent=0]
 ----
 
 ==== Method selection algorithm
@@ -448,7 +448,7 @@ Consider the following method definitions:
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_methods,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_methods,indent=0]
 ----
 
 Perhaps as expected, calling `method` with `String` and `Integer` parameters,
@@ -456,7 +456,7 @@ invokes our third method definition.
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=call_single_method,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=call_single_method,indent=0]
 ----
 
 Of more interest here is when the types are not known at compile time.
@@ -467,7 +467,7 @@ and will invoke each of our methods once (and normally, no casting is needed):
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=call_multi_methods,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=call_multi_methods,indent=0]
 ----
 
 For each of the first two of our three method invocations an exact match of argument types was found.
@@ -493,49 +493,49 @@ a| Given these interface and method definitions:
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interfaces,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interfaces,indent=0]
 ----
 
 The directly implemented interface will match:
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interfaces_usage,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interfaces_usage,indent=0]
 ----
 
 | An Object array is preferred over an Object.
 a|
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=object_array_over_object,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=object_array_over_object,indent=0]
 ----
 
 | Non-vararg variants are favored over vararg variants.
 a|
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=non_varargs_over_vararg,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=non_varargs_over_vararg,indent=0]
 ----
 
 | If two vararg variants are applicable, the one which uses the minimum number of vararg arguments is preferred.
 a|
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=minimal_varargs,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=minimal_varargs,indent=0]
 ----
 
 | Interfaces are preferred over super classes.
 a|
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interface_over_super,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_method_distance_interface_over_super,indent=0]
 ----
 
 | For a primitive argument type, a declared parameter type which is the same or slightly larger is preferred.
 a|
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=primitive_larger_over_smaller,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=primitive_larger_over_smaller,indent=0]
 ----
 |====
 
@@ -543,14 +543,14 @@ In the case where two variants have exactly the same distance, this is deemed am
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_method_ambiguous,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_method_ambiguous,indent=0]
 ----
 
 Casting can be used to select the desired method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=multi_method_ambiguous_cast,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=multi_method_ambiguous_cast,indent=0]
 ----
 
 
@@ -562,7 +562,7 @@ as shown in the following example which can throw a `FileNotFoundException` if t
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=idiomatic_method_declaration,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=idiomatic_method_declaration,indent=0]
 ----
 
 Nor will you be required to surround the call to the `badRead` method in the previous example within a try/catch
@@ -576,7 +576,7 @@ Using an explicit checked exception declaration is illustrated in the following
 
 [source,groovy]
 ----
-include::{includedir}/../test/objectorientation/MethodsTest.groovy[tags=checked_method_declaration,indent=0]
+include::{projectdir}/src/spec/test/objectorientation/MethodsTest.groovy[tags=checked_method_declaration,indent=0]
 ----
 
 === Fields and properties
@@ -593,7 +593,7 @@ A field is a member of a class or a trait which has:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=field_declaration,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=field_declaration,indent=0]
 ----
 <1> a `private` field named `id`, of type `int`
 <2> a `protected` field named `description`, of type `String`
@@ -603,7 +603,7 @@ A field may be initialized directly at declaration:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=field_initialization,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=field_initialization,indent=0]
 ----
 <1> the private field `id` is initialized with `IDGenerator.next()`
 
@@ -612,7 +612,7 @@ is a good idea to use strong typing for fields:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=typing_fields,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=typing_fields,indent=0]
 ----
 <1> the field `mapping` doesn't declare a type
 <2> the field `mapping` has a strong type
@@ -641,7 +641,7 @@ Groovy will then generate the getters/setters appropriately. For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=properties_definition,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=properties_definition,indent=0]
 ----
 <1> creates a backing `private String name` field, a `getName` and a `setName` method
 <2> creates a backing `private int age` field, a `getAge` and a `setAge` method
@@ -650,7 +650,7 @@ If a property is declared `final`, no setter is generated:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=readonly_property,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=readonly_property,indent=0]
 ----
 <1> defines a read-only property of type `String`
 <2> defines a read-only property of type `int`
@@ -662,7 +662,7 @@ which defines the property:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=property_access,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=property_access,indent=0]
 ----
 <1> `this.name` will directly access the field because the property is accessed from within the class that defines it
 <2> similarily a read access is done directly on the `name` field
@@ -678,7 +678,7 @@ It is possible to list the properties of a class thanks to the meta `properties`
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=properties_meta,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=properties_meta,indent=0]
 ----
 
 By convention, Groovy will recognize properties even if there is no backing field
@@ -687,7 +687,7 @@ that follow the Java Beans specification. For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=pseudo_properties,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=pseudo_properties,indent=0]
 ----
 <1> writing `p.name` is allowed because there is a pseudo-property `name`
 <2> reading `p.age` is allowed because there is a pseudo-readonly property `age`
@@ -741,7 +741,7 @@ similar way to interfaces, using the `@interface` keyword:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=define_annotation,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=define_annotation,indent=0]
 ----
 
 An annotation may define members in the form of methods without bodies and an optional default value. The possible
@@ -758,12 +758,12 @@ For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_string,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_string_default,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_int,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_class,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_annotation,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=ann_member_enum,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_string,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_string_default,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_int,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_class,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_annotation,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_member_enum,indent=0]
 ----
 <1> an annotation defining a `value` member of type `String`
 <2> an annotation defining a `value` member of type `String` with a default value of `something`
@@ -782,7 +782,7 @@ An annotation can be applied on various elements of the code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=apply_annotation_1,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=apply_annotation_1,indent=0]
 ----
 <1> `@SomeAnnotation` applies to the `someMethod` method
 <2> `@SomeAnnotation` applies to the `SomeClass` class
@@ -794,7 +794,7 @@ declare that an annotation can be applied to a class or a method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=ann_target,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_target,indent=0]
 ----
 <1> the `@Target` annotation is meant to annotate an annotation with a scope.
 <2> `@SomeAnnotation` will therefore only be allowed on `TYPE` or `METHOD`
@@ -810,7 +810,7 @@ When an annotation is used, it is required to set at least all members that do n
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=annotation_value_set,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=annotation_value_set,indent=0]
 ----
 
 However it is possible to omit `value=` in the declaration of the value of an annotation if the member `value` is the
@@ -818,7 +818,7 @@ only one being set:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=annotation_value_set_option,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=annotation_value_set_option,indent=0]
 ----
 <1> we can omit the `statusCode` because it has a default value, but `value` needs to be set
 <2> since `value` is the only mandatory member without a default, we can omit `value=`
@@ -831,7 +831,7 @@ the jdk:java.lang.annotation.Retention[Retention] annotation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=ann_retention,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=ann_retention,indent=0]
 ----
 <1> the `@Retention` annotation annotates the `@SomeAnnotation` annotation
 <2> so `@SomeAnnotation` will have a `SOURCE` retention
@@ -850,21 +850,21 @@ One could write the following code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=closure_ann_example,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=closure_ann_example,indent=0]
 ----
 
 For the `@OnlyIf` annotation to accept a `Closure` as an argument, you only have to declare the `value` as a `Class`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=closure_ann_def,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=closure_ann_def,indent=0]
 ----
 
 To complete the example, let's write a sample runner that would use that information:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=closure_ann_runner,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=closure_ann_runner,indent=0]
 ----
 <1> create a new instance of the class passed as an argument (the task class)
 <2> emulate an environment which is JDK 6 and not Windows
@@ -882,7 +882,7 @@ Then the runner can be used this way:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=closure_ann_runner_exec,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=closure_ann_runner_exec,indent=0]
 ----
 
 ==== Meta-annotations
@@ -900,7 +900,7 @@ with both:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=transactionalservice_class,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=transactionalservice_class,indent=0]
 ----
 
 Given the multiplication of annotations that you could add to the same class, a meta-annotation
@@ -909,7 +909,7 @@ we might want to write this instead:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=transactionalservice_class2,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=transactionalservice_class2,indent=0]
 ----
 <1> `@TransactionalService` is a meta-annotation
 
@@ -918,7 +918,7 @@ list of annotations it is collecting. In our case, the `@TransactionalService` a
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=metaann_ts,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=metaann_ts,indent=0]
 ----
 <1> annotate the meta-annotation with `@Service`
 <2> annotate the meta-annotation with `@Transactional`
@@ -946,7 +946,7 @@ replace `@TransactionalService` with `@Transactional` and `@Service`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=annotations_expanded,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=annotations_expanded,indent=0]
 ----
 
 The conversion from a meta-annotation to the collected annotations is performed during the
@@ -963,15 +963,15 @@ we will imagine two annotations, each of them accepting one argument:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=collected_ann_explosive,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=collected_ann_explosive,indent=0]
 ----
 
 And suppose that you want create a meta-annotation named `@Explosive`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=collected_ann_explosive,indent=0]
-include::{includedir}/../test/ClassTest.groovy[tags=collector_ann_explosive,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=collected_ann_explosive,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=collector_ann_explosive,indent=0]
 ----
 
 By default, when the annotations are replaced, they will get the
@@ -980,7 +980,7 @@ the meta-annotation supports overriding specific values:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=example_bomb,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=example_bomb,indent=0]
 ----
 <1> the `after` value provided as a parameter to `@Explosive` overrides the one defined in the `@Timeout` annotation
 
@@ -989,7 +989,7 @@ will copy the annotation value to all annotations that accept this parameter:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=collector_ann_same_values,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=collector_ann_same_values,indent=0]
 ----
 <1> the `@Foo` annotation defines the `value` member of type `String`
 <2> the `@Bar` annotation also defines the `value` member of type `String`
@@ -1064,14 +1064,14 @@ The naive implementation here would not work:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=compiledynamic_naive,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=compiledynamic_naive,indent=0]
 ----
 
 Instead, we will define it like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=compiledynamic_def_fixed,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=compiledynamic_def_fixed,indent=0]
 ----
 
 The first thing you may notice is that our interface is no longer
@@ -1084,7 +1084,7 @@ Here is how the custom processor is implemented:
 [source,groovy]
 .CompileDynamicProcessor.groovy
 ----
-include::{includedir}/../test/ClassTest.groovy[tags=compiledynamic_processor,indent=0]
+include::{projectdir}/src/spec/test/ClassTest.groovy[tags=compiledynamic_processor,indent=0]
 ----
 <1> our custom processor is written in Groovy, and for better compilation performance, we use static compilation
 <2> the custom processor has to extend gapi:org.codehaus.groovy.transform.AnnotationCollectorTransform[AnnotationCollectorTransform]
@@ -1114,5 +1114,5 @@ single one corresponding to `@CompileStatic(TypeCheckingMode.SKIP)`.
 (TBD)
 
 
-include::{includedir}/fragment_traits.adoc[leveloffset=+1]
+include::{projectdir}/src/spec/doc/core-traits.adoc[leveloffset=+1]
 
diff --git a/src/spec/doc/core-operators.adoc b/src/spec/doc/core-operators.adoc
index d7d2b39..011c057 100644
--- a/src/spec/doc/core-operators.adoc
+++ b/src/spec/doc/core-operators.adoc
@@ -68,7 +68,7 @@ Here are a few examples of usage of those operators:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=binary_arith_ops,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=binary_arith_ops,indent=0]
 ----
 
 === Unary operators
@@ -77,7 +77,7 @@ The `+` and `-` operators are also available as unary operators:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=unary_plus_minus,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=unary_plus_minus,indent=0]
 ----
 <1> Note the usage of parentheses to surround an expression to apply the unary minus to that surrounded expression.
 
@@ -86,7 +86,7 @@ both in prefix and postfix notation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=plusplus_minusminus,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=plusplus_minusminus,indent=0]
 ----
 <1> The postfix increment will increment `a` after the expression has been evaluated and assigned into `b`
 <2> The postfix decrement will decrement `c` after the expression has been evaluated and assigned into `d`
@@ -110,7 +110,7 @@ Let's see them in action:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=binary_assign_operators,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=binary_assign_operators,indent=0]
 ----
 
 == Relational operators
@@ -154,7 +154,7 @@ Here are some examples of simple number comparisons using these operators:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=simple_relational_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=simple_relational_op,indent=0]
 ----
 
 Both `===` and `!==` are supported which are the same as calling the `is()` method,
@@ -191,7 +191,7 @@ Let's illustrate them with the following examples:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=logical_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=logical_op,indent=0]
 ----
 <1> "not" false is true
 <2> true "and" true is true
@@ -203,7 +203,7 @@ The logical "not" has a higher priority than the logical "and".
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=logical_precendence_1,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=logical_precendence_1,indent=0]
 ----
 <1> Here, the assertion is true (as the expression in parentheses is false), because "not" has a higher precedence than "and", so it only applies to the first "false" term; otherwise, it would have applied to the result of the "and", turned it into true, and the assertion would have failed
 
@@ -211,7 +211,7 @@ The logical "and" has a higher priority than the logical "or".
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=logical_precendence_2,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=logical_precendence_2,indent=0]
 ----
 <1> Here, the assertion is true, because "and" has a higher precedence than "or", therefore the "or" is executed last and returns true, having one true argument; otherwise, the "and" would have executed last and returned false, having one false argument, and the assertion would have failed
 
@@ -225,7 +225,7 @@ The right operand will be evaluated only if the left operand is true.
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=logical_shortcircuit,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=logical_shortcircuit,indent=0]
 ----
 <1> We create a function that sets the `called` flag to true whenever it's called
 <2> In the first case, after resetting the called flag, we confirm that if the left operand to `||` is true, the function is not called, as `||` short-circuits the evaluation of the right operand
@@ -251,7 +251,7 @@ otherwise, the result will be of type `int`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=bitwise_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=bitwise_op,indent=0]
 ----
 <1> bitwise and
 <2> bitwise and returns common bits
@@ -283,7 +283,7 @@ otherwise, the result will be of type `int`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=bit_shift_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=bit_shift_op,indent=0]
 ----
 <1> `equals` method used instead of `==` to confirm result type
 
@@ -298,10 +298,10 @@ particular, it is possible to combine the `not` operator with the <<core-semanti
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=conditional_op_not,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=conditional_op_not,indent=0]
 ----
 <1> the negation of `true` is `false`
-<2> 'foo' is a non-empty string, evaluating to `true`, so negation returns `false`
+<2> 'foo' is a non empty string, evaluating to `true`, so negation returns `false`
 <3> '' is an empty string, evaluating to `false`, so negation returns `true`
 
 === Ternary operator
@@ -311,20 +311,20 @@ The ternary operator is a shortcut expression that is equivalent to an if/else b
 Instead of:
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=conditional_op_ternary_if,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=conditional_op_ternary_if,indent=0]
 ----
 
 You can write:
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=conditional_op_ternary_ternary,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=conditional_op_ternary_ternary,indent=0]
 ----
 
 The ternary operator is also compatible with the <<core-semantics.adoc#Groovy-Truth,Groovy truth>>, so you can make it even simpler:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=conditional_op_ternary_groovytruth,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=conditional_op_ternary_groovytruth,indent=0]
 ----
 
 === Elvis operator
@@ -335,7 +335,7 @@ a 'sensible default' value if an expression resolves to `false`-ish (as in
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=conditional_op_elvis,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=conditional_op_elvis,indent=0]
 ----
 <1> with the ternary operator, you have to repeat the value you want to assign
 <2> with the Elvis operator, the value, which is tested, is used if it is not `false`-ish
@@ -375,7 +375,7 @@ navigation operator will simply return `null` instead of throwing an exception,
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=nullsafe,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=nullsafe,indent=0]
 ----
 <1> `find` will return a `null` instance
 <2> use of the null-safe operator prevents from a `NullPointerException`
@@ -387,7 +387,7 @@ Normally in Groovy, when you write code like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=direct_field_class,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=direct_field_class,indent=0]
 ----
 <1> public field `name`
 <2> a getter for `name` that returns a custom string
@@ -398,7 +398,7 @@ you want to retrieve the field instead of calling the getter, you can use the di
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=direct_field_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=direct_field_op,indent=0]
 ----
 <1> use of `.@` forces usage of the field instead of the getter
 
@@ -410,7 +410,7 @@ in order to call it later:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_pointer,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_pointer,indent=0]
 ----
 <1> the `str` variable contains a `String`
 <2> we store a reference to the `toUpperCase` method on the `str` instance inside a variable named `fun`
@@ -423,7 +423,7 @@ convert an existing method for the needs of the strategy pattern:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_pointer_strategy,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_pointer_strategy,indent=0]
 ----
 <1> the `transform` method takes each element of the list and calls the `action` closure on them, returning a new list
 <2> we define a function that takes a `Person` and returns a `String`
@@ -437,7 +437,7 @@ will be done at runtime:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_pointer_dispatch,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_pointer_dispatch,indent=0]
 ----
 <1> define an overloaded `doSomething` method accepting a `String` as an argument
 <2> define an overloaded `doSomething` method accepting an `Integer` as an argument
@@ -449,7 +449,7 @@ To align with Java 8 method reference expectations, in Groovy 3 and above, you c
 method name to obtain a method pointer to the constructor:
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_pointer_new,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_pointer_new,indent=0]
 ----
 
 Also in Groovy 3 and above, you can obtain a method pointer to an instance method of a class.
@@ -457,7 +457,7 @@ This method pointer takes an additional parameter being the receiver instance to
 invoke the method on:
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_pointer_class_instance,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_pointer_class_instance,indent=0]
 ----
 For backwards compatibility, any static methods that happen to have the correct
 parameters for the call will be given precedence over instance methods for this case.
@@ -477,7 +477,7 @@ Some examples highlighting various supported method reference cases are shown in
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=method_refs,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=method_refs,indent=0]
 ----
 <1> class instance method reference: add(BigInteger val) is an instance method in BigInteger
 <2> object instance method reference: add(BigInteger val) is an instance method for object 3G
@@ -488,7 +488,7 @@ Some examples highlighting various supported constructor reference cases are sho
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=constructor_refs,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=constructor_refs,indent=0]
 ----
 <1> class constructor reference
 <2> array constructor reference
@@ -501,7 +501,7 @@ The pattern operator (`~`) provides a simple way to create a `java.util.regex.Pa
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=pattern_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=pattern_op,indent=0]
 ----
 
 while in general, you find the pattern operator with an expression in a slashy-string, it can be used with any kind of
@@ -509,7 +509,7 @@ while in general, you find the pattern operator with an expression in a slashy-s
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=pattern_op_variants,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=pattern_op_variants,indent=0]
 ----
 <1> using single quote strings
 <2> using double quotes strings
@@ -522,7 +522,7 @@ Alternatively to building a pattern, you can use the find operator `=~` to direc
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=pattern_matcher_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=pattern_matcher_op,indent=0]
 ----
 <1> `=~` creates a matcher against the `text` variable, using the pattern on the right hand side
 <2> the return type of `=~` is a `Matcher`
@@ -539,7 +539,7 @@ and requires a strict match of the input string:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=pattern_matcher_strict_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=pattern_matcher_strict_op,indent=0]
 ----
 <1> `==~` matches the subject with the regular expression, but match must be strict
 <2> the return type of `==~` is therefore a `boolean`
@@ -554,7 +554,7 @@ of an aggregate object. It is equivalent to calling the action on each item and
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreaddot,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreaddot,indent=0]
 ----
 <1> build a list of `Car` items. The list is an aggregate of objects.
 <2> call the spread operator on the list, accessing the `make` property of each item
@@ -571,7 +571,7 @@ it will return null instead of throwing a `NullPointerException`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreaddot_nullsafe,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreaddot_nullsafe,indent=0]
 ----
 <1> build a list for which of of the elements is `null`
 <2> using the spread operator will *not* throw a `NullPointerException`
@@ -581,7 +581,7 @@ The spread operator can be used on any class which implements the `Iterable` int
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreaddot_iterable,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreaddot_iterable,indent=0]
 ----
 
 Use multiple invocations of the spread-dot operator (here `cars*.models*.name`) when
@@ -589,14 +589,14 @@ working with aggregates of data structures which themselves contain aggregates:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreaddot_multilevel,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreaddot_multilevel,indent=0]
 ----
 
 Consider using the `collectNested` DGM method instead of the spread-dot operator for collections of collections:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreaddot_alternative,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreaddot_alternative,indent=0]
 ----
 
 ==== Spreading method arguments
@@ -607,28 +607,28 @@ following method signature:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreadmethodargs_method,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreadmethodargs_method,indent=0]
 ----
 
 then if you have the following list:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreadmethodargs_args,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreadmethodargs_args,indent=0]
 ----
 
 you can call the method without having to define intermediate variables:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreadmethodargs_assert,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreadmethodargs_assert,indent=0]
 ----
 
 It is even possible to mix normal arguments with spread ones:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spreadmethodargs_mixed,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spreadmethodargs_mixed,indent=0]
 ----
 
 ==== Spread list elements
@@ -637,7 +637,7 @@ When used inside a list literal, the spread operator acts as if the spread eleme
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spread_list,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spread_list,indent=0]
 ----
 <1> `items` is a list
 <2> we want to insert the contents of the `items` list directly into `list` without having to call `addAll`
@@ -650,7 +650,7 @@ the contents of a map into another map literal, like in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spread_map,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spread_map,indent=0]
 ----
 <1> `m1` is the map that we want to inline
 <2> we use the `*:m1` notation to spread the contents of `m1` into `map`
@@ -660,7 +660,7 @@ The position of the spread map operator is relevant, like illustrated in the fol
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spread_map_position,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spread_map_position,indent=0]
 ----
 <1> `m1` is the map that we want to inline
 <2> we use the `*:m1` notation to spread the contents of `m1` into `map`, but redefine the key `d` **after** spreading
@@ -672,7 +672,7 @@ Groovy supports the concept of ranges and provides a notation (`..`) to create r
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=intrange,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=intrange,indent=0]
 ----
 <1> a simple range of integers, stored into a local variable
 <2> an `IntRange`, with inclusive bounds
@@ -686,7 +686,7 @@ For example, you can create a range of characters this way:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=charrange,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=charrange,indent=0]
 ----
 
 === Spaceship operator
@@ -695,7 +695,7 @@ The spaceship operator (`pass:[<=>]`) delegates to the `compareTo` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=spaceship,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=spaceship,indent=0]
 ----
 
 [[subscript-operator]]
@@ -706,7 +706,7 @@ the left hand side or the right hand side of an assignment:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=subscript_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=subscript_op,indent=0]
 ----
 <1> `[2]` can be used instead of `getAt(2)`
 <2> if on left hand side of an assignment, will call `putAt`
@@ -720,7 +720,7 @@ objects:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=subscript_destructuring,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=subscript_destructuring,indent=0]
 ----
 <1> the `User` class defines a custom `getAt` implementation
 <2> the `User` class defines a custom `putAt` implementation
@@ -765,7 +765,7 @@ to calling `contains`, like in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=membership_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=membership_op,indent=0]
 ----
 <1> equivalent to calling `list.contains('Emmy')` or `list.isCase('Emmy')`
 
@@ -776,7 +776,7 @@ If you want to compare reference equality, you should use `is` like in the follo
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=identity_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=identity_op,indent=0]
 ----
 <1> Create a list of strings
 <2> Create another list of strings containing the same elements
@@ -790,7 +790,7 @@ being compatible for assignment. Let's take an example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=coerce_op_cast,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=coerce_op_cast,indent=0]
 ----
 <1> `Integer` is not assignable to a `String`, so it will produce a `ClassCastException` at runtime
 
@@ -798,7 +798,7 @@ This can be fixed by using _coercion_ instead:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=coerce_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=coerce_op,indent=0]
 ----
 <1> `Integer` is not assignable to a `String`, but use of `as` will _coerce_ it to a `String`
 
@@ -808,7 +808,7 @@ rules are found. Custom conversion rules may be implemented thanks to the `asTyp
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=coerce_op_custom,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=coerce_op_custom,indent=0]
 ----
 <1> the `User` class defines a custom conversion rule from `User` to `Identifiable`
 <2> we create an instance of `User`
@@ -823,7 +823,7 @@ same name in Java 7. It is used to indicate that generic types should be inferre
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=diamond_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=diamond_op,indent=0]
 ----
 
 In dynamic Groovy, this is totally unused. In statically type checked Groovy, it is also optional since the Groovy
@@ -836,7 +836,7 @@ The call operator `()` is used to call a method named `call` implicitly. For any
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=call_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=call_op,indent=0]
 ----
 <1> `MyCallable` defines a method named `call`. Note that it doesn't need to implement `java.util.concurrent.Callable`
 <2> we can call the method using the classic method call syntax
@@ -881,7 +881,7 @@ class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=operator_overload_class,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=operator_overload_class,indent=0]
 ----
 <1> `Bucket` implements a special method called `plus()`
 
@@ -889,7 +889,7 @@ Just by implementing the `plus()` method, the `Bucket` class can now be used wit
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=operator_overload_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=operator_overload_op,indent=0]
 ----
 <1> The two `Bucket` objects can be added together with the `+` operator
 
@@ -900,14 +900,14 @@ the statement
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=operator_overload_mixed_op,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=operator_overload_mixed_op,indent=0]
 ----
 
 by implementing the `plus()` method with this signature:
 
 [source,groovy]
 ----
-include::{includedir}/../test/OperatorsTest.groovy[tags=operator_overload_mixed_class,indent=0]
+include::{projectdir}/src/spec/test/OperatorsTest.groovy[tags=operator_overload_mixed_class,indent=0]
 ----
 
 Here is a complete list of the operators and their corresponding methods:
diff --git a/src/spec/doc/core-program-structure.adoc b/src/spec/doc/core-program-structure.adoc
index 5debd6a..7fa0e2b 100644
--- a/src/spec/doc/core-program-structure.adoc
+++ b/src/spec/doc/core-program-structure.adoc
@@ -31,7 +31,7 @@ Defining a package is very similar to Java:
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=package_statement,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=package_statement,indent=0]
 ----
 
 To refer to some class `Foo` in the `com.yoursite.com` package you will need to use the fully qualified name `com.yoursite.com.Foo`, or else you can use an `import` statement as we'll see below.
@@ -44,7 +44,7 @@ For example, Groovy provides several builder classes, such as `MarkupBuilder`. `
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=import_statement,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=import_statement,indent=0]
 ----
 
 === Default imports
@@ -53,7 +53,7 @@ Default imports are the imports that Groovy language provides by default. For ex
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=default_import,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=default_import,indent=0]
 ----
 
 The same code in Java needs an import statement to `Date` class like this: ++import java.util.Date++. Groovy by default imports these classes for you. 
@@ -80,7 +80,7 @@ A simple import is an import statement where you fully define the class name alo
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=import_statement,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=import_statement,indent=0]
 ----
 
 === Star import
@@ -89,14 +89,14 @@ Groovy, like Java, provides a special way to import all classes from a package u
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=multiple_import,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=multiple_import,indent=0]
 ----
 
 That's perfectly valid code. But with a `*` import, we can achieve the same effect with just one line. The star imports all the classes under package `groovy.xml`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=star_import,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=star_import,indent=0]
 ----
 
 One problem with `*` imports is that they can clutter your local namespace. But with the kinds of aliasing provided by Groovy, this can be solved easily. 
@@ -107,14 +107,14 @@ Groovy's static import capability allows you to reference imported classes as if
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=static_imports,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=static_imports,indent=0]
 ----
 
 This is similar to Java's static import capability but is a more dynamic than Java in that it allows you to define methods with the same name as an imported method as long as you have different types:
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=static_import_same_method_name_different_parameter_type,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=static_import_same_method_name_different_parameter_type,indent=0]
 ----
 <1> static import of method
 <2> declaration of method with same name as method statically imported above, but with a different parameter type
@@ -128,7 +128,7 @@ Static imports with the `as` keyword provide an elegant solution to namespace pr
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=static_importswithas,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=static_importswithas,indent=0]
 ----
 
 Now, that's clean!
@@ -142,7 +142,7 @@ The class `java.lang.Math` has static methods named `sin` and `cos` which fit ou
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=static_importswithstar,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=static_importswithstar,indent=0]
 ----
 
 As you can see, we were able to access the methods `sin` and `cos` directly, without the `Math.` prefix.
@@ -155,7 +155,7 @@ For example we can import `java.sql.Date` as `SQLDate` and use it in the same fi
 
 [source,groovy]
 ----
-include::{includedir}/../test/PackageTest.groovy[tags=alias_import,indent=0]
+include::{projectdir}/src/spec/test/PackageTest.groovy[tags=alias_import,indent=0]
 ----
 
 == Scripts versus classes
@@ -166,7 +166,7 @@ Groovy supports both scripts and classes. Take the following code for example:
 [source,groovy]
 .Main.groovy
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=groovy_class_with_main_method,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=groovy_class_with_main_method,indent=0]
 ----
 <1> define a `Main` class, the name is arbitrary
 <2> the `public static void main(String[])` method is usable as the main method of the class
@@ -178,7 +178,7 @@ Groovy makes it easier, the following code is equivalent:
 [source,groovy]
 .Main.groovy
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=groovy_script,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=groovy_script,indent=0]
 ----
 
 A script can be considered as a class without needing to declare it, with some differences.
@@ -192,7 +192,7 @@ following:
 [source,groovy]
 .Main.groovy
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=groovy_script_equiv,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=groovy_script_equiv,indent=0]
 ----
 <1> The `Main` class extends the `groovy.lang.Script` class
 <2> `groovy.lang.Script` requires a `run` method returning a value
@@ -209,7 +209,7 @@ It is possible to define methods into a script, as illustrated here:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=method_in_script,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=method_in_script,indent=0]
 ----
 
 You can also mix methods and code. The generated script class will carry all methods into the script class, and
@@ -217,7 +217,7 @@ assemble all script bodies into the `run` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=multiple_methods_assembly,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=multiple_methods_assembly,indent=0]
 ----
 <1> script begins
 <2> a method is defined within the script body
@@ -227,7 +227,7 @@ This code is internally converted into:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=multiple_methods_assembly_equiv,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=multiple_methods_assembly_equiv,indent=0]
 ----
 <1> the `power` method is copied as is into the generated script class
 <2> first statement is copied into the `run` method
@@ -243,14 +243,14 @@ Variables in a script do not require a type definition. This means that this scr
 
 [source,groovy]
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=script_with_variables,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=script_with_variables,indent=0]
 ----
 
 will behave the same as:
 
 [source,groovy]
 ----
-include::{includedir}/../test/ScriptsAndClassesSpecTest.groovy[tags=script_with_untyped_variables,indent=0]
+include::{projectdir}/src/spec/test/ScriptsAndClassesSpecTest.groovy[tags=script_with_untyped_variables,indent=0]
 ----
 
 However, there is a semantic difference between the two:
diff --git a/src/spec/doc/core-semantics.adoc b/src/spec/doc/core-semantics.adoc
index 36a1e89..dd12db3 100644
--- a/src/spec/doc/core-semantics.adoc
+++ b/src/spec/doc/core-semantics.adoc
@@ -31,7 +31,7 @@ Variables can be defined using either their type (like `String`) or by using the
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=variable_definition_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=variable_definition_example,indent=0]
 ----
 
 `def` and `var` act as a type placeholder, i.e. a replacement for the type name,
@@ -49,7 +49,7 @@ in which case it's like having a declaration and assignment (which we cover next
 
 [NOTE]
 Variable definition types can be refined by using generics, like in `List<String> names`.
-To learn more about the generics support, please read the <<core-object-orientation.adoc#generics,generics section>>.
+To learn more about the generics support, please read the <<generics,generics section>>.
 
 === Variable assignment
 
@@ -57,7 +57,7 @@ You can assign values to variables for later use. Try the following:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=variable_assignment_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=variable_assignment_example,indent=0]
 ----
 
 ==== Multiple assignment
@@ -66,28 +66,28 @@ Groovy supports multiple assignment, i.e. where multiple variables can be assign
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_example,indent=0]
 ----
 
 You can provide types as part of the declaration if you wish:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_with_types,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_with_types,indent=0]
 ----
 
 As well as used when declaring variables it also applies to existing variables:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_with_existing_variables,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_with_existing_variables,indent=0]
 ----
 
 The syntax works for arrays as well as lists, as well as methods that return either of these:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_with_arrays_and_lists,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_with_arrays_and_lists,indent=0]
 ----
 
 ==== Overflow and Underflow
@@ -96,20 +96,20 @@ If the left hand side has too many variables, excess ones are filled with null's
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_overflow,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_overflow,indent=0]
 ----
 
 If the right hand side has too many variables, the extra ones are ignored:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=multiple_assignment_underflow,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=multiple_assignment_underflow,indent=0]
 ----
 
 ==== Object destructuring with multiple assignment
 
-In the section describing Groovy's operators,
-the case of the <<core-operators.adoc#subscript-operator,subscript operator>> has been covered,
+In the section describing the various <<groovy-operators,Groovy operators>>,
+the case of the <<subscript-operator,subscript operator>> has been covered,
 explaining how you can override the `getAt()`/`putAt()` method.
 
 With this technique, we can combine multiple assignments and the subscript operator methods to implement _object destructuring_.
@@ -119,14 +119,14 @@ and notice our implementation of the `getAt()` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=coordinates-class,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=coordinates-class,indent=0]
 ----
 
 Now let's instantiate this class and destructure its longitude and latitude:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=destructuring,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=destructuring,indent=0]
 ----
 <1> we create an instance of the `Coordinates` class
 <2> then, we use a multiple assignment to get the individual longitude and latitude values
@@ -140,7 +140,7 @@ Groovy supports the usual if - else syntax from Java
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=if_else_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=if_else_example,indent=0]
 ----
 
 Groovy also supports the normal Java "nested" if then else if syntax:
@@ -164,7 +164,7 @@ One difference though is that the Groovy switch statement can handle any kind of
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=switch_case_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=switch_case_example,indent=0]
 ----
 
 Switch supports the following kinds of comparisons:
@@ -184,7 +184,7 @@ Groovy supports the standard Java / C for loop:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=classic_for_loop_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=classic_for_loop_example,indent=0]
 ----
 
 ===== Enhanced classic Java-style for loop
@@ -231,7 +231,7 @@ The for loop in Groovy is much simpler and works with any kind of array, collect
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=groovy_for_loop_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=groovy_for_loop_example,indent=0]
 ----
 
 [NOTE]
@@ -243,7 +243,7 @@ Groovy supports the usual while {...} loops like Java:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=while_loop_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=while_loop_example,indent=0]
 ----
 
 ===== do/while loop
@@ -274,14 +274,14 @@ NOTE: Braces are required around each block's body.
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=try_catch_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=try_catch_example,indent=0]
 ----
 
 We can put code within a 'finally' clause following a matching 'try' clause, so that regardless of whether the code in the 'try' clause throws an exception, the code in the finally clause will always execute:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SemanticsTest.groovy[tags=try_catch_finally_example,indent=0]
+include::{projectdir}/src/spec/test/SemanticsTest.groovy[tags=try_catch_finally_example,indent=0]
 ----
 
 ==== Multi-catch
@@ -372,7 +372,7 @@ expression being asserted. For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_code_1,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_code_1,indent=0]
 ----
 
 Will yield:
@@ -380,21 +380,21 @@ Will yield:
 ----
 Caught: Assertion failed:
 
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_error_1,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_error_1,indent=0]
 ----
 
 Power asserts become very interesting when the expressions are more complex, like in the next example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_code_2,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_code_2,indent=0]
 ----
 
 Which will print the value for each sub-expression:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_error_2,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_error_2,indent=0]
 ----
 
 In case you don't want a pretty printed error message like above, you can fallback to a custom error message by
@@ -402,14 +402,14 @@ changing the optional message part of the assertion, like in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_code_3,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_code_3,indent=0]
 ----
 
 Which will print the following error message:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/PowerAssertTest.groovy[tags=assert_error_3,indent=0]
+include::{projectdir}/src/spec/test/semantics/PowerAssertTest.groovy[tags=assert_error_3,indent=0]
 ----
 
 
@@ -420,7 +420,7 @@ the code easier to read like in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/LabelsTest.groovy[tags=test_labels,indent=0]
+include::{projectdir}/src/spec/test/semantics/LabelsTest.groovy[tags=test_labels,indent=0]
 ----
 
 Despite not changing the semantics of the labelled statement, it is possible to use labels in the `break` instruction
@@ -429,7 +429,7 @@ a bad practice:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/LabelsTest.groovy[tags=label_bad_practice,indent=0]
+include::{projectdir}/src/spec/test/semantics/LabelsTest.groovy[tags=label_bad_practice,indent=0]
 ----
 
 It is important to understand that by default labels have no impact on the semantics of the code, however they belong to the abstract
@@ -445,7 +445,7 @@ does to make testing easier.
 [[gpath_expressions]]
 === GPath expressions
 ////
-This is covered in {rootprojectdir}/subprojects/groovy-xml/{specfolder}/xml-userguide.adoc, where the legacy codehaus GPath wiki page
+This is covered in {projectdir}/subprojects/groovy-xml/{specfolder}/xml-userguide.adoc, where the legacy codehaus GPath wiki page
 have been converted.
 Current section should explain what is an GPath expression (not just example, but more like a formal language specification, but kept simple).
 
@@ -483,14 +483,14 @@ class having another method named `aMethodFoo`
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_reflection_1,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_on_reflection_1,indent=0]
 ----
 
 the following GPath expression will get the name of that method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_reflection_2,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_on_reflection_2,indent=0]
 ----
 
 _More precisely_, the above GPath expression produces a list of String, each being the name of an existing method on `this` where that name ends with `Foo`.
@@ -499,14 +499,14 @@ Now, given the following methods also defined in that class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_reflection_3,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_on_reflection_3,indent=0]
 ----
 
 then the following GPath expression will get the names of *(1)* and *(3)*, but not *(2)* or *(0)*:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_reflection_4,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_on_reflection_4,indent=0]
 ----
 
 ==== Expression Deconstruction
@@ -535,7 +535,7 @@ return methodNames;
 Array access notation can also be used in a GPath expression where a collection is present :
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_array_access_1,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_array_access_1,indent=0]
 ----
 
 NOTE: array access are zero-based in GPath expressions
@@ -545,7 +545,7 @@ NOTE: array access are zero-based in GPath expressions
 Here is an example with a XML document and various form of GPath expressions:
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_xml_1,indent=0]
+include::{projectdir}/src/spec/test/semantics/GPathTest.groovy[tags=gpath_on_xml_1,indent=0]
 ----
 
 <1> There is one `level` node under `root`
@@ -557,7 +557,7 @@ include::{includedir}/../test/semantics/GPathTest.groovy[tags=gpath_on_xml_1,ind
 
 === Number promotion
 
-The rules of number promotion are specified in the section on <<core-syntax.adoc#_math_operations,math operations>>.
+The rules of number promotion are specified in the section on <<_math_operations,math operations>>.
 
 
 [[closure-coercion]]
@@ -568,34 +568,34 @@ A SAM type is a type which defines a single abstract method. This includes:
 [source,groovy]
 .Functional interfaces
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=filter_sam_type,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=filter_sam_type,indent=0]
 ----
 
 [source,groovy]
 .Abstract classes with single abstract method
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=greeter_sam_type,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=greeter_sam_type,indent=0]
 ----
 
 Any closure can be converted into a SAM type using the `as` operator:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=assertions_explicit_closure_to_sam,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=assertions_explicit_closure_to_sam,indent=0]
 ----
 
 However, the `as Type` expression is optional since Groovy 2.2.0. You can omit it and simply write:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=assertions_implicit_closure_to_sam,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=assertions_implicit_closure_to_sam,indent=0]
 ----
 
 which means you are also allowed to use method pointers, as shown in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=assertions_implicit_closure_to_sam_and_method_pointer,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=assertions_implicit_closure_to_sam_and_method_pointer,indent=0]
 ----
 
 ==== Calling a method accepting a SAM type with a closure
@@ -605,21 +605,21 @@ a SAM type. Imagine the following method:
 
 [source,groovy]
 -----
-include::{includedir}/../test/CoercionTest.groovy[tags=method_accepting_filter,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=method_accepting_filter,indent=0]
 -----
 
 Then you can call it with a closure, without having to create an explicit implementation of the interface:
 
 [source,groovy]
 -----
-include::{includedir}/../test/CoercionTest.groovy[tags=method_call_with_explicit_coercion,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=method_call_with_explicit_coercion,indent=0]
 -----
 
 But since Groovy 2.2.0, you are also able to omit the explicit coercion and call the method as if it used a closure:
 
 [source,groovy]
 -----
-include::{includedir}/../test/CoercionTest.groovy[tags=method_call_with_implicit_coercion,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=method_call_with_implicit_coercion,indent=0]
 -----
 
 As you can see, this has the advantage of letting you use the closure syntax for method calls, that is to say put the
@@ -632,21 +632,21 @@ following interface:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=foobar_interface,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=foobar_interface,indent=0]
 ----
 
 You can coerce a closure into the interface using the `as` keyword:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=foobar2closure_coercion,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=foobar2closure_coercion,indent=0]
 ----
 
 This produces a class for which all methods are implemented using the closure:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=foobarintf_assertions,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=foobarintf_assertions,indent=0]
 ----
 
 But it is also possible to coerce a closure to any class. For example, we can replace the `interface` that we defined
@@ -654,7 +654,7 @@ with `class` without changing the assertions:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=closure2foobarclass,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=closure2foobarclass,indent=0]
 ----
 
 === Map to type coercion
@@ -666,7 +666,7 @@ coercion of a map into an `Iterator`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=coerce_map_to_iterator,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=coerce_map_to_iterator,indent=0]
 ----
 
 Of course this is a rather contrived example, but illustrates the concept. You only need to implement those methods
@@ -676,10 +676,10 @@ as in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=define_x_interface,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=call_existing_method,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=call_non_existing_method,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=call_notimplemented_method,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=define_x_interface,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=call_existing_method,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=call_non_existing_method,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=call_notimplemented_method,indent=0]
 ----
 
 The type of the exception depends on the call itself:
@@ -693,35 +693,35 @@ Groovy allows transparent `String` (or `GString`) to enum values coercion. Imagi
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=state_enum,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=state_enum,indent=0]
 ----
 
 then you can assign a string to the enum without having to use an explicit `as` coercion:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=enum_coerce_assignment,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=enum_coerce_assignment,indent=0]
 ----
 
 It is also possible to use a `GString` as the value:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=enum_coerce_assignment_gstring,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=enum_coerce_assignment_gstring,indent=0]
 ----
 
 
 However, this would throw a runtime error (`IllegalArgumentException`):
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=enum_coerce_assignment_wrong,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=enum_coerce_assignment_wrong,indent=0]
 ----
 
 Note that it is also possible to use implicit coercion in switch statements:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=enum_switch_method,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=enum_switch_method,indent=0]
 ----
 
 in particular, see how the `case` use string constants. But if you call a method that uses an enum with a `String`
@@ -729,7 +729,7 @@ argument, you still have to use an explicit `as` coercion:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=enum_switch_test,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=enum_switch_test,indent=0]
 ----
 
 === Custom type coercion
@@ -740,9 +740,9 @@ imagine you defined two classes, `Polar` and `Cartesian`, like in the following
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_header,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_footer,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=cartesian_class,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_header,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_footer,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=cartesian_class,indent=0]
 ----
 
 And that you want to convert from polar coordinates to cartesian coordinates. One way of doing this is to define
@@ -750,22 +750,22 @@ the `asType` method in the `Polar` class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_astype,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_astype,indent=0]
 ----
 
 which allows you to use the `as` coercion operator:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_astype_assert,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_astype_assert,indent=0]
 ----
 
 Putting it all together, the `Polar` class looks like this:
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_header,indent=0]
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_astype,indent=4]
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_class_footer,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_header,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_astype,indent=4]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_class_footer,indent=0]
 ----
 
 but it is also possible to define `asType` outside of the `Polar` class, which can be practical if you want to define
@@ -774,7 +774,7 @@ a metaclass:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=polar_metaclass_astype,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=polar_metaclass_astype,indent=0]
 ----
 
 === Class literals vs variables and the as operator
@@ -783,28 +783,28 @@ Using the `as` keyword is only possible if you have a static reference to a clas
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=as_keyword,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=as_keyword,indent=0]
 ----
 
 But what if you get the class by reflection, for example by calling `Class.forName`?
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=clazz_greeter_header,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=clazz_greeter_header,indent=0]
 ----
 
 Trying to use the reference to the class with the `as` keyword would fail:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=incorrect_as_usage,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=incorrect_as_usage,indent=0]
 ----
 
 It is failing because the `as` keyword only works with class literals. Instead, you need to call the `asType` method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/CoercionTest.groovy[tags=fixed_as_usage,indent=0]
+include::{projectdir}/src/spec/test/CoercionTest.groovy[tags=fixed_as_usage,indent=0]
 ----
 
 == Optionality
@@ -815,14 +815,14 @@ Method calls can omit the parentheses if there is at least one parameter and the
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=optional_parentheses,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=optional_parentheses,indent=0]
 ----
 
 Parentheses are required for method calls without parameters or ambiguous method calls: 
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=required_parentheses,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=required_parentheses,indent=0]
 ----
 
 === Optional semicolons
@@ -833,21 +833,21 @@ This means that:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=single_statement_with_semicolon,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=single_statement_with_semicolon,indent=0]
 ----
 
 can be more idiomatically written as:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=single_statement_without_semicolon,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=single_statement_without_semicolon,indent=0]
 ----
 
 Multiple statements in a line require semicolons to separate them:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=statements_separated_by_semicolon,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=statements_separated_by_semicolon,indent=0]
 ----
 
 === Optional return keyword
@@ -856,14 +856,14 @@ In Groovy, the last expression evaluated in the body of a method or a closure is
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=return_keyword,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=return_keyword,indent=0]
 ----
 
 Can be shortened to:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=omitted_return_keyword,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=omitted_return_keyword,indent=0]
 ----
 
 === Optional public keyword
@@ -872,14 +872,14 @@ By default, Groovy classes and methods are `public`. Therefore this class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=public_keyword,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=public_keyword,indent=0]
 ----
 
 is identical to this class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/OptionalityTest.groovy[tags=omitted_public,indent=0]
+include::{projectdir}/src/spec/test/semantics/OptionalityTest.groovy[tags=omitted_public,indent=0]
 ----
 
 [[Groovy-Truth]]
@@ -891,56 +891,56 @@ Groovy decides whether a expression is true or false by applying the rules given
 True if the corresponding Boolean value is `true`.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=boolean_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=boolean_truth,indent=0]
 ----
 
 === Collections and Arrays
 Non-empty Collections and arrays are true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=collection_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=collection_truth,indent=0]
 ----
 
 === Matchers
 True if the Matcher has at least one match.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=matcher_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=matcher_truth,indent=0]
 ----
 
 === Iterators and Enumerations
 Iterators and Enumerations with further elements are coerced to true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=iterator_enumeration_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=iterator_enumeration_truth,indent=0]
 ----
 
 === Maps
 Non-empty Maps are evaluated to true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=map_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=map_truth,indent=0]
 ----
 
 === Strings
 Non-empty Strings, GStrings and CharSequences are coerced to true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=string_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=string_truth,indent=0]
 ----
 
 === Numbers
 Non-zero numbers are true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=number_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=number_truth,indent=0]
 ----
 
 === Object References
 Non-null object references are coerced to true.
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=object_truth,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=object_truth,indent=0]
 ----
 
 === Customizing the truth with asBoolean() methods
@@ -948,14 +948,14 @@ include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=object_tr
 In order to customize whether groovy evaluates your object to `true` or `false` implement the `asBoolean()` method:
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=asBoolean_object,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=asBoolean_object,indent=0]
 ----
 
 Groovy will call this method to coerce your object to a boolean value, e.g.:
 
 [source,groovy]
 ----
-include::{includedir}/../test/semantics/TheGroovyTruthTest.groovy[tags=asBoolean_usage,indent=0]
+include::{projectdir}/src/spec/test/semantics/TheGroovyTruthTest.groovy[tags=asBoolean_usage,indent=0]
 ----
 
 == Typing
@@ -967,7 +967,7 @@ language, Groovy naturally implements that feature, for example when you declare
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/OptionalTypingTest.groovy[tags=optionaltyping_var,indent=0]
+include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=optionaltyping_var,indent=0]
 ----
 <1> `foo` is declared using an explicit type, `String`
 <2> we can call the `toUpperCase` method on a `String`
@@ -976,7 +976,7 @@ Groovy will let you write this instead:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/OptionalTypingTest.groovy[tags=optionaltyping_var_def,indent=0]
+include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=optionaltyping_var_def,indent=0]
 ----
 <1> `foo` is declared using `def`
 <2> we can still call the `toUpperCase` method, because the type of `aString` is resolved at runtime
@@ -988,7 +988,7 @@ Likewise, Groovy doesn't make it mandatory to declare the types of a parameter i
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/OptionalTypingTest.groovy[tags=optionaltyping_orig,indent=0]
+include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=optionaltyping_orig,indent=0]
 ----
 
 can be rewritten using `def` as both return type and parameter types, in order to take advantage of duck typing, as
@@ -996,7 +996,7 @@ illustrated in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/OptionalTypingTest.groovy[tags=optionaltyping_def,indent=0]
+include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=optionaltyping_def,indent=0]
 ----
 <1> both the return type and the parameter types use `def`
 <2> it makes it possible to use the method with `String`
@@ -1012,7 +1012,7 @@ between a method declaration and a method call, like illustrated in this example
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/OptionalTypingTest.groovy[tags=optionaltyping_notype,indent=0]
+include::{projectdir}/src/spec/test/typing/OptionalTypingTest.groovy[tags=optionaltyping_notype,indent=0]
 ----
 <1> if we want to omit the return type, an explicit modifier has to be set.
 <2> it is still possible to use the method with `String`
@@ -1034,7 +1034,7 @@ following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_intro,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_intro,indent=0]
 ----
 <1> the `Person` class only defines two properties, `firstName` and `lastName`
 <2> we can create an instance of Person
@@ -1047,7 +1047,7 @@ runtime metaprogramming. So just adding this line after the declaration of the `
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_intro_magic,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_intro_magic,indent=0]
 ----
 
 This means that in general, in Groovy, you can't make any assumption about the type of an object beyond its declaration
@@ -1079,14 +1079,14 @@ The `groovy.transform.TypeChecked` annotation enables type checking. It can be p
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=typechecked_class,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=typechecked_class,indent=0]
 ----
 
 Or on a method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=typechecked_method,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=typechecked_method,indent=0]
 ----
 
 In the first case, all methods, properties, fields, inner classes, ... of the annotated class will be type checked, whereas
@@ -1099,7 +1099,7 @@ to skip a method by annotating it with `@TypeChecked(TypeCheckingMode.SKIP)`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_skip,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_skip,indent=0]
 ----
 <1> the `GreetingService` class is marked as type checked
 <2> so the `greeting` method is automatically type checked
@@ -1125,7 +1125,7 @@ An object `o` of type `A` can be assigned to a variable of type `T` if and only
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_equals,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_equals,indent=0]
 ----
 ====
 
@@ -1137,7 +1137,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_equ
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_specialcase,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_specialcase,indent=0]
 ----
 ====
 
@@ -1149,8 +1149,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_spe
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_null,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_null2prim,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_null,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_null2prim,indent=0]
 ----
 ====
 
@@ -1162,8 +1162,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_nul
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_array,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_array,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_fail,indent=0]
 ----
 ====
 
@@ -1175,8 +1175,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_arr
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_list,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_list_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_list,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_array_list_fail,indent=0]
 ----
 ====
 
@@ -1188,8 +1188,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_arr
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_superclass,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_superclass_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_superclass,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_superclass_fail,indent=0]
 ----
 ====
 
@@ -1202,8 +1202,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_sup
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_interface,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_interface_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_interface,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_interface_fail,indent=0]
 ----
 ====
 
@@ -1215,7 +1215,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_int
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_prim,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_prim,indent=0]
 ----
 ====
 
@@ -1227,7 +1227,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_pri
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_closure_coercion,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_closure_coercion,indent=0]
 ----
 ====
 
@@ -1244,42 +1244,42 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_closure_co
 |Any but BigDecimal or BigInteger
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_double,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_double,indent=0]
 ----
 
 |Float
 |Any type but BigDecimal, BigInteger or Double
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_float,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_float,indent=0]
 ----
 
 |Long
 |Any type but BigDecimal, BigInteger, Double or Float
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_long,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_long,indent=0]
 ----
 
 |Integer
 |Any type but BigDecimal, BigInteger, Double, Float or Long
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_int,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_int,indent=0]
 ----
 
 |Short
 |Any type but BigDecimal, BigInteger, Double, Float, Long or Integer
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_short,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_short,indent=0]
 ----
 
 |Byte
 |Byte
 | [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_byte,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_assign_to_byte,indent=0]
 ----
 
 |===
@@ -1296,21 +1296,21 @@ For example, instead of writing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_classic,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_classic,indent=0]
 ----
 
 You can use a "list constructor":
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_list,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_list,indent=0]
 ----
 
 or a "map constructor":
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_map,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_ctor_point_map,indent=0]
 ----
 
 If you use a map constructor, additional checks are done on the keys of the map to check if a property of the same name
@@ -1318,7 +1318,7 @@ is defined. For example, the following will fail at compile time:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_ctor_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_ctor_fail,indent=0]
 ----
 <1> The type checker will throw an error `No such property: age for class: Person` at compile time
 
@@ -1337,7 +1337,7 @@ An argument `o` of type `A` can be used for a parameter of type `T` if and only
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_equals,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_equals,indent=0]
 ----
 ====
 
@@ -1349,7 +1349,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_e
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_specialcase,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_specialcase,indent=0]
 ----
 ====
 
@@ -1361,8 +1361,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_s
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_null,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_null2prim,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_null,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_null2prim,indent=0]
 ----
 ====
 
@@ -1374,8 +1374,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_n
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_array,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_array_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_array,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_array_fail,indent=0]
 ----
 ====
 
@@ -1387,8 +1387,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_a
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_superclass,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_superclass_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_superclass,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_superclass_fail,indent=0]
 ----
 ====
 
@@ -1400,8 +1400,8 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_s
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_interface,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_interface_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_interface,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_interface_fail,indent=0]
 ----
 ====
 
@@ -1413,7 +1413,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_i
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_prim,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_argparam_prim,indent=0]
 ----
 ====
 
@@ -1425,7 +1425,7 @@ include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_argparam_p
 ====
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=stc_arg_closure_coercion,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=stc_arg_closure_coercion,indent=0]
 ----
 ====
 
@@ -1436,7 +1436,7 @@ illustrated in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=method_not_type_checked,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=method_not_type_checked,indent=0]
 ----
 <1> `printLine` is an error, but since we're in a dynamic mode, the error is not caught at compile time
 
@@ -1447,7 +1447,7 @@ not in such a case, `@TypeChecked` comes handy:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=method_type_checked,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=method_type_checked,indent=0]
 ----
 <1> `printLine` is this time a compile-time error
 
@@ -1463,7 +1463,7 @@ is not aware of any kind of *runtime* metaprogramming that you do. This means th
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=ducktyping_failure,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=ducktyping_failure,indent=0]
 ----
 <1> we define a `Duck` class which defines a `quack` method
 <2> we define another `QuackingBird` class which also defines a `quack` method
@@ -1488,8 +1488,8 @@ The simplest example is inferring the type of a variable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=simple_var_type_inference,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=simple_var_type_inference_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=simple_var_type_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=simple_var_type_inference_fail,indent=0]
 ----
 <1> a variable is declared using the `def` keyword
 <2> calling `toUpperCase` is allowed by the type checker
@@ -1505,7 +1505,7 @@ look at this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=typeinference_field_vs_local_variable,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=typeinference_field_vs_local_variable,indent=0]
 ----
 <1> `someUntypedField` uses `def` as a declaration type
 <2> `someTypedField` uses `String` as a declaration type
@@ -1543,49 +1543,49 @@ The inferred type of a literal depends on the elements of the literal, as illust
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=empty_list_literal_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=empty_list_literal_inference,indent=0]
 ----
 |`java.util.List`
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=list_literal_inference_simple,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=list_literal_inference_simple,indent=0]
 ----
 |`java.util.List<String>`
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=list_literal_inference_gstring,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=list_literal_inference_gstring,indent=0]
 ----
 |`java.util.List<GString>` be careful, a `GString` is *not* a `String`!
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=empty_map_literal_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=empty_map_literal_inference,indent=0]
 ----
 |`java.util.LinkedHashMap`
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=map_literal_inference_simple,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=map_literal_inference_simple,indent=0]
 ----
 |`java.util.LinkedHashMap<String,String>`
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=map_literal_inference_gstring,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=map_literal_inference_gstring,indent=0]
 ----
 |`java.util.LinkedHashMap<GString,String>` be careful, the key is a `GString`!
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=intRange_literal_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=intRange_literal_inference,indent=0]
 ----
 |`groovy.lang.IntRange`
 
 |[source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=charRange_literal_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=charRange_literal_inference,indent=0]
 ----
 |`groovy.lang.Range<String>` : uses the type of the bounds to infer the component type of the range
 
@@ -1613,7 +1613,7 @@ are both `String`, then the LUB (least upper bound) of both is also `String`.
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_simple,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_simple,indent=0]
 ----
 <1> the LUB of `String` and `String` is `String`
 <2> the LUB of `ArrayList` and `LinkedList` is their common super type, `AbstractList`
@@ -1628,7 +1628,7 @@ let's continue with this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_complex,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_complex,indent=0]
 ----
 
 What is the least upper bound of `Bottom` and `SerializableFooImpl`? They don't have a common super class (apart from `Object`),
@@ -1640,7 +1640,7 @@ components is inferred as the least upper bound. We can illustrate why this is i
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_collection_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=least_upper_bound_collection_inference,indent=0]
 ----
 <1> the `Greeter` interface defines a single method, `greet`
 <2> the `Salute`  interface defines a single method, `salute`
@@ -1667,7 +1667,7 @@ In normal, non type checked, Groovy, you can write things like:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=instanceof_inference,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=instanceof_inference,indent=0]
 ----
 <1> guard the method call with an `instanceof` check
 <2> make the call
@@ -1677,7 +1677,7 @@ require to cast `o` to a `Greeter` before calling the `greeting` method, because
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=instanceof_java_equiv,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=instanceof_java_equiv,indent=0]
 ----
 
 However, in Groovy, even if you add `@TypeChecked` (and thus activate type checking) on the `doSomething` method, the
@@ -1691,7 +1691,7 @@ the compiler is capable of inferring the type of variables in the flow of the co
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flowtyping_basics,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flowtyping_basics,indent=0]
 ----
 <1> first, `o` is declared using `def` and assigned a `String`
 <2> the compiler inferred that `o` is a `String`, so calling `toUpperCase` is allowed
@@ -1703,7 +1703,7 @@ if you replace the last assignment with:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flowtyping_basics_fail,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flowtyping_basics_fail,indent=0]
 ----
 
 The type checker will now fail at compile time, because it knows that `o` is a `double` when `toUpperCase` is called,
@@ -1715,7 +1715,7 @@ can assign to the variable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints,indent=0]
 ----
 <1> `list` is declared as an unchecked `List` and assigned a list literal of `String`s
 <2> this line passes compilation because of flow typing: the type checker knows that `list` is at this point a `List<String>`
@@ -1726,7 +1726,7 @@ the component type. Therefore, such code would fail compilation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints_failure,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints_failure,indent=0]
 ----
 <1> `list` is inferred as `List<String>`
 <2> so adding an `int` to a `List<String>` is a compile-time error
@@ -1735,7 +1735,7 @@ Fixing this requires adding an explicit generic type to the declaration:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints_fixed,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flowtyping_typeconstraints_fixed,indent=0]
 ----
 <1> `list` declared as `List<? extends Serializable>` and initialized with an empty list
 <2> elements added to the list conform to the declaration type of the list
@@ -1746,8 +1746,8 @@ consider the behavior of this code in Java:
 
 [source,java]
 ----
-include::{includedir}/../test/typing/TypeCheckingJavaTest.java[tags=java_method_selection_head,indent=0]
-include::{includedir}/../test/typing/TypeCheckingJavaTest.java[tags=java_method_selection_body,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingJavaTest.java[tags=java_method_selection_head,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingJavaTest.java[tags=java_method_selection_body,indent=0]
 ----
 <1> `o` is declared as an `Object` and assigned a `String`
 <2> we call the `compute` method with `o`
@@ -1762,7 +1762,7 @@ In Groovy, we could write:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=groovy_method_selection,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=groovy_method_selection,indent=0]
 ----
 
 But this time, it will return `6`, because the method which is chosen is chosen *at runtime*, based on the _actual_
@@ -1788,8 +1788,8 @@ likely to alter the inferred type of a variable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flow_lub_ifelse_header,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=flow_lub_ifelse_test,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flow_lub_ifelse_header,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=flow_lub_ifelse_test,indent=0]
 ----
 <1> if `someCondition` is true, `o` is assigned a `Top`
 <2> if `someCondition` is false, `o` is assigned a `Bottom`
@@ -1807,7 +1807,7 @@ which is defined outside of a closure, but used inside a closure, as in this exa
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_definition,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_definition,indent=0]
 ----
 <1> a variable named `text` is declared
 <2> `text` is used from inside a closure. It is a _closure shared variable_.
@@ -1817,7 +1817,7 @@ variable can be reassigned inside a closure:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_ex1,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_ex1,indent=0]
 ----
 
 The problem is that a closure is an independent block of code that can be executed (or not) at *any* time. In particular,
@@ -1828,7 +1828,7 @@ this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_ex2,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=closure_shared_variable_ex2,indent=0]
 ----
 <1> a closure-shared variable is first assigned a `Top`
 <2> inside the closure, it is assigned a `Bottom`
@@ -1851,7 +1851,7 @@ The first thing that the type checker is capable of doing is inferring the _retu
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=closure_return_type_inf,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=closure_return_type_inf,indent=0]
 ----
 <1> a closure is defined, and it returns a string (more precisely a `GString`)
 <2> we call the closure and assign the result to a variable
@@ -1870,7 +1870,7 @@ following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=method_return_type_matters,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=method_return_type_matters,indent=0]
 ----
 <1> class `A` defines a method `compute` which effectively returns a `String`
 <2> this will fail compilation because the return type of `compute` is `def`(aka `Object`)
@@ -1898,7 +1898,7 @@ to infer the parameter types:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_failure,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_failure,indent=0]
 ----
 <1> the `inviteIf` method accepts a `Person` and a `Closure`
 <2> we call it with a `Person` and a `Closure`
@@ -1915,7 +1915,7 @@ the type of `it`. This means that the method call needs to be rewritten like thi
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround,indent=0]
 ----
 <1> the type of `it` needs to be declared explicitly
 
@@ -1930,7 +1930,7 @@ SAM type:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_sam,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_sam,indent=0]
 ----
 <1> declare a `SAM` interface with an `apply` method
 <2> `inviteIf` now uses a `Predicate<Person>` instead of a `Closure<Boolean>`
@@ -1960,9 +1960,9 @@ Let's illustrate this by fixing the original example, introducing the `@ClosureP
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_imports,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_method,indent=0]
-include::{includedir}/../test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_call,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_imports,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_method,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingTest.groovy[tags=cl_pt_workaround_closureparams_call,indent=0]
 ----
 <1> the closure parameter is annotated with `@ClosureParams`
 <2> it's not necessary to use an explicit type for `it`, which is inferred
@@ -1988,17 +1988,17 @@ various bundled type hints, illustrated in the table below:
 |The first (resp. second, third) parameter type of the method +
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_firstparam,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_firstparam,indent=0]
 ----
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_secondparam,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_secondparam,indent=0]
 ----
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_thirdparam,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_thirdparam,indent=0]
 ----
 
 |`FirstParam.FirstGenericType` +
@@ -2008,7 +2008,7 @@ include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_
 |The first generic type of the first (resp. second, third) parameter of the method +
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_firstgt,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_firstgt,indent=0]
 ----
 
 Variants for `SecondGenericType` and `ThirdGenericType` exist for all `FirstParam`, `SecondParam` and `ThirdParam`
@@ -2019,7 +2019,7 @@ type hints.
 |A type hint for which the type of closure parameters comes from the options string. +
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_simpletype,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_simpletype,indent=0]
 ----
 
 This type hint supports a *single* signature and each of the parameter is specified as a value of the _options_ array
@@ -2031,7 +2031,7 @@ using a fully-qualified type name or a primitive type.
 to the key and the value. +
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_mapentry,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_mapentry,indent=0]
 ----
 
 This type hint *requires* that the first argument is a `Map` type, and infers the closure parameter types from the map
@@ -2042,7 +2042,7 @@ actual key/value types.
 |Infers closure parameter types from the abstract method of some type. A signature is inferred for *each* abstract method. +
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_abstract_type,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_abstract_type,indent=0]
 ----
 
 If there are multiple signatures like in the example above, the type checker will *only* be able to infer the types of
@@ -2062,21 +2062,21 @@ A single signature for a closure accepting a `String`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_1,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_1,indent=0]
 ----
 
 A polymorphic closure, accepting either a `String` or a `String, Integer`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_2,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_2,indent=0]
 ----
 
 A polymorphic closure, accepting either a `T` or a pair `T,T`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_3,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingHintsTest.groovy[tags=typehint_from_string_3,indent=0]
 ----
 
 |===
@@ -2120,7 +2120,7 @@ by definition only correct if no runtime specific behavior occurs. For example,
 [[typechecked-defeated]]
 [source,groovy]
 ----
-include::{includedir}/../test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe,indent=0]
+include::{projectdir}/src/spec/test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe,indent=0]
 ----
 
 There are two `compute` methods. One accepts a `String` and returns an `int`, the other accepts an `int` and returns
@@ -2131,7 +2131,7 @@ Now, before calling `test()`, consider adding the following line:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_magic,indent=0]
+include::{projectdir}/src/spec/test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_magic,indent=0]
 ----
 
 Using runtime metaprogramming, we're actually modifying the behavior of the `compute(String)` method, so that instead of
@@ -2157,8 +2157,8 @@ with `@CompileStatic`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_compilestatic,indent=0]
-include::{includedir}/../test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_magic,indent=0]
+include::{projectdir}/src/spec/test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_compilestatic,indent=0]
+include::{projectdir}/src/spec/test/typing/StaticCompilationIntroTest.groovy[tags=intro_typesafe_magic,indent=0]
 test()
 ----
 
@@ -2185,5 +2185,5 @@ There is only one way to determine which version you should choose: measuring. T
 *and* the JVM that you use, the performance can be significantly different. In particular, the _invokedynamic_ version of
 Groovy is very sensitive to the JVM version in use.
 
-include::{includedir}/fragment_type-checking-extensions.adoc[leveloffset=+1]
+include::type-checking-extensions.adoc[leveloffset=+1]
 
diff --git a/src/spec/doc/core-syntax.adoc b/src/spec/doc/core-syntax.adoc
index f3ef359..3b2a75e 100644
--- a/src/spec/doc/core-syntax.adoc
+++ b/src/spec/doc/core-syntax.adoc
@@ -34,7 +34,7 @@ The characters following `//`, until the end of the line, are considered part of
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=single_line_comment,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=single_line_comment,indent=0]
 ----
 
 === Multiline comment
@@ -46,7 +46,7 @@ Multiline comments can thus be put at the end of a statement, or even inside a s
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=multiline_comment,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=multiline_comment,indent=0]
 ----
 
 === Groovydoc comment
@@ -64,7 +64,7 @@ you should prepend those constructs with the comment right before it.
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=groovydoc_comment,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=groovydoc_comment,indent=0]
 ----
 
 Groovydoc follows the same conventions as Java's own Javadoc.
@@ -103,7 +103,7 @@ and the `groovy` command is available on the `PATH`.
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=shebang_comment_line,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=shebang_comment_line,indent=0]
 ----
 
 NOTE: The `#` character must be the first character of the file. Any indentation would yield a compilation error.
@@ -187,21 +187,21 @@ Here are a few examples of valid identifiers (here, variable names):
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=valid_identifiers,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=valid_identifiers,indent=0]
 ----
 
 But the following ones are invalid identifiers:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=invalid_identifiers,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=invalid_identifiers,indent=0]
 ----
 
 All keywords are also valid identifiers when following a dot:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=keywords_valid_id_after_dot,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=keywords_valid_id_after_dot,indent=0]
 ----
 
 === Quoted identifiers
@@ -213,7 +213,7 @@ but which are allowed by Groovy when quoted. For example, characters like a dash
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=quoted_id,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=quoted_id,indent=0]
 ----
 
 As we shall see in the <<all-strings,following section on strings>>, Groovy provides different string literals.
@@ -221,7 +221,7 @@ All kind of strings are actually allowed after the dot:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=quoted_id_with_all_strings,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=quoted_id_with_all_strings,indent=0]
 ----
 
 There's a difference between plain character strings and Groovy's GStrings (interpolated strings),
@@ -229,7 +229,7 @@ as in that the latter case, the interpolated values are inserted in the final st
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=quoted_id_with_gstring,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=quoted_id_with_gstring,indent=0]
 ----
 
 [[all-strings]]
@@ -245,7 +245,7 @@ Single-quoted strings are a series of characters surrounded by single quotes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_1,indent=0]
 ----
 
 NOTE: Single-quoted strings are plain `java.lang.String` and don't support interpolation.
@@ -256,7 +256,7 @@ All the Groovy strings can be concatenated with the `+` operator:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_plus,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_plus,indent=0]
 ----
 
 === Triple-single-quoted string
@@ -265,7 +265,7 @@ Triple-single-quoted strings are a series of characters surrounded by triplets o
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=triple_single_0,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=triple_single_0,indent=0]
 ----
 
 NOTE: Triple-single-quoted strings are plain `java.lang.String` and don't support interpolation.
@@ -276,7 +276,7 @@ and without concatenation or newline escape characters:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=triple_single_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=triple_single_1,indent=0]
 ----
 
 If your code is indented, for example in the body of the method of a class, your string will contain the whitespace of the indentation.
@@ -287,7 +287,7 @@ When creating a string as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=triple_single_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=triple_single_2,indent=0]
 ----
 
 You will notice that the resulting string contains a newline character as first character.
@@ -295,7 +295,7 @@ It is possible to strip that character by escaping the newline with a backslash:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=triple_single_3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=triple_single_3,indent=0]
 ----
 
 ==== Escaping special characters
@@ -304,14 +304,14 @@ You can escape single quotes with the backslash character to avoid terminating t
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_2,indent=0]
 ----
 
 And you can escape the escape character itself with a double backslash:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_3,indent=0]
 ----
 
 Some special characters also use the backslash as escape character:
@@ -360,7 +360,7 @@ For example, the Euro currency symbol can be represented with:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_4,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_4,indent=0]
 ----
 
 === Double-quoted string
@@ -369,7 +369,7 @@ Double-quoted strings are a series of characters surrounded by double quotes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=string_5,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=string_5,indent=0]
 ----
 
 NOTE: Double-quoted strings are plain `java.lang.String` if there's no interpolated expression,
@@ -391,14 +391,14 @@ Here, we have a string with a placeholder referencing a local variable:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_1,indent=0]
 ----
 
 Any Groovy expression is valid, as we can see in this example with an arithmetic expression:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_2,indent=0]
 ----
 
 [NOTE]
@@ -410,7 +410,7 @@ In addition to `${}` placeholders, we can also use a lone `$` sign prefixing a d
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_3,indent=0]
 ----
 
 But only dotted expressions of the form `a.b`, `a.b.c`, etc, are valid. Expressions containing parentheses like method calls,
@@ -419,14 +419,14 @@ Given the following variable definition of a number:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_4,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_4,indent=0]
 ----
 
 The following statement will throw a `groovy.lang.MissingPropertyException` because Groovy believes you're trying to access the `toString` property of that number, which doesn't exist:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_5,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_5,indent=0]
 ----
 
 NOTE: You can think of `"$number.toString()"` as being interpreted by the parser as `"${number.toString}()"`.
@@ -435,9 +435,9 @@ Similarly, if the expression is ambiguous, you need to keep the curly braces:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_3b,indent=0]
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_3b2,indent=0]
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_3b3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_3b,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_3b2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_3b3,indent=0]
 ----
 
 If you need to escape the `$` or `${}` placeholders in a GString so they appear as is without interpolation,
@@ -445,7 +445,7 @@ you just need to use a `\` backslash character to escape the dollar sign:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_6,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_6,indent=0]
 ----
 
 ==== Special case of interpolating closure expressions
@@ -454,7 +454,7 @@ So far, we've seen we could interpolate arbitrary expressions inside the `${}` p
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=closure_in_gstring_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=closure_in_gstring_1,indent=0]
 ----
 <1> The closure is a parameterless closure which doesn't take arguments.
 <2> Here, the closure takes a single `java.io.StringWriter` argument, to which you can append content  with the `<<` leftShift operator.
@@ -467,7 +467,7 @@ Let's consider the following sample:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=closure_in_gstring_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=closure_in_gstring_2,indent=0]
 ----
 <1> We define a `number` variable containing `1` that we then interpolate within two GStrings,
 as an expression in `eagerGString` and as a closure in `lazyGString`.
@@ -490,7 +490,7 @@ the `toString()` method of the GString is automatically and transparently called
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=java_gstring_interop_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=java_gstring_interop_1,indent=0]
 ----
 <1> We create a GString variable
 <2> We double check it's an instance of the GString
@@ -508,7 +508,7 @@ Even for the same resulting string, GStrings and Strings don't have the same has
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_hashcode_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_hashcode_1,indent=0]
 ----
 
 GString and Strings having different hashCode values, using GString as Map keys should be avoided,
@@ -516,7 +516,7 @@ especially if we try to retrieve an associated value with a String instead of a
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=gstring_hashcode_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=gstring_hashcode_2,indent=0]
 ----
 <1> The map is created with an initial pair whose key is a GString
 <2> When we try to fetch the value with a String key, we will not find it, as Strings and GString have different hashCode values
@@ -527,7 +527,7 @@ Triple-double-quoted strings behave like double-quoted strings, with the additio
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=triple_double_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=triple_double_1,indent=0]
 ----
 
 NOTE: Neither double quotes nor single quotes need be escaped in triple-double-quoted strings.
@@ -542,28 +542,28 @@ Example of a slashy string:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=slashy_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=slashy_1,indent=0]
 ----
 
 Only forward slashes need to be escaped with a backslash:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=slashy_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=slashy_2,indent=0]
 ----
 
 Slashy strings are multiline:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=slashy_3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=slashy_3,indent=0]
 ----
 
 Slashy strings can be thought of as just another way to define a GString but with different escaping rules. They hence support interpolation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=slashy_4,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=slashy_4,indent=0]
 ----
 
 ==== Special cases
@@ -573,7 +573,7 @@ That's why the following assert would actually not compile as it would look like
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=slashy_5,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=slashy_5,indent=0]
 ----
 
 As slashy strings were mostly designed to make regexp easier so a few things that
@@ -598,7 +598,7 @@ Here's an example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=dollar_slashy_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=dollar_slashy_1,indent=0]
 ----
 
 It was created to overcome some of the limitations of the slashy string escaping rules.
@@ -658,7 +658,7 @@ However, you can be explicit about making a Groovy string an actual character, b
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=char,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=char,indent=0]
 ----
 <1> by being explicit when declaring a variable holding the character by specifying the `char` type
 <2> by using type coercion with the `as` operator
@@ -686,7 +686,7 @@ You can create integral numbers of those types with the following declarations:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=int_decl,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=int_decl,indent=0]
 ----
 
 If you use optional typing by using the `def` keyword, the type of the integral number will vary:
@@ -696,14 +696,14 @@ For positive numbers:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=wide_int_positive,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=wide_int_positive,indent=0]
 ----
 
 As well as for negative numbers:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=wide_int_negative,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=wide_int_negative,indent=0]
 ----
 
 ==== Alternative non-base 10 representations
@@ -716,7 +716,7 @@ Binary numbers start with a `0b` prefix:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=binary_literal_example,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=binary_literal_example,indent=0]
 ----
 
 ===== Octal literal
@@ -725,7 +725,7 @@ Octal numbers are specified in the typical format of `0` followed by octal digit
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=octal_literal_example,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=octal_literal_example,indent=0]
 ----
 
 ===== Hexadecimal literal
@@ -734,7 +734,7 @@ Hexadecimal numbers are specified in the typical format of `0x` followed by hex
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=hexadecimal_literal_example,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=hexadecimal_literal_example,indent=0]
 ----
 
 === Decimal literals
@@ -749,7 +749,7 @@ You can create decimal numbers of those types with the following declarations:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=float_decl,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=float_decl,indent=0]
 ----
 
 Decimals can use exponents, with the `e` or `E` exponent letter, followed by an optional sign,
@@ -757,7 +757,7 @@ and a integral number representing the exponent:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=float_exp,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=float_exp,indent=0]
 ----
 
 Conveniently for exact decimal number calculations, Groovy choses `java.lang.BigDecimal` as its decimal number type.
@@ -772,7 +772,7 @@ When writing long literal numbers, it’s harder on the eye to figure out how so
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=underscore_in_number_example,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=underscore_in_number_example,indent=0]
 ----
 
 === Number type suffixes
@@ -807,12 +807,12 @@ Examples:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=number_type_suffixes_example,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=number_type_suffixes_example,indent=0]
 ----
 
 === Math operations
 
-Although <<core-operators.adoc#_operators,operators>> are covered in more detail elsewhere, it's important to discuss the behavior of math operations
+Although <<_operators,operators>> are covered later on, it's important to discuss the behavior of math operations
 and what their resulting types are.
 
 Division and power binary operations aside (covered below),
@@ -987,23 +987,23 @@ We can illustrate those rules with a few examples:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=number_power,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=number_power,indent=0]
 ----
 
 == Booleans
 
 Boolean is a special data type that is used to represent truth values: `true` and `false`.
-Use this data type for simple flags that track true/false <<core-operators.adoc#_conditional_operators,conditions>>.
+Use this data type for simple flags that track true/false <<_conditional_operators,conditions>>.
 
 Boolean values can be stored in variables, assigned into fields, just like any other data type:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=variable_store_boolean_value,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=variable_store_boolean_value,indent=0]
 ----
 
 `true` and `false` are the only two primitive boolean values.
-But more complex boolean expressions can be represented using <<core-operators.adoc#_logical_operators,logical operators>>.
+But more complex boolean expressions can be represented using <<_bitwise_and_logical_operators,logical operators>>.
 
 In addition, Groovy has <<core-semantics.adoc#Groovy-Truth,special rules>> (often referred to as _Groovy Truth_)
 for coercing non-boolean objects to a boolean value.
@@ -1017,7 +1017,7 @@ unless you decide to specify otherwise, as we shall see later on.
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=list_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=list_1,indent=0]
 ----
 <1> We define a list numbers delimited by commas and surrounded by square brackets, and we assign that list into a variable
 <2> The list is an instance of Java's `java.util.List` interface
@@ -1027,7 +1027,7 @@ In the above example, we used a homogeneous list, but you can also create lists
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=list_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=list_2,indent=0]
 ----
 <1> Our list here contains a number, a string and a boolean value
 
@@ -1037,7 +1037,7 @@ thanks to using type coercion with the `as` operator, or with explicit type decl
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=coercion_of_list,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=coercion_of_list,indent=0]
 ----
 <1> We use coercion with the `as` operator to explicitly request a `java.util.LinkedList` implementation
 <2> We can say that the variable holding the list literal is of type `java.util.LinkedList`
@@ -1048,7 +1048,7 @@ and use the `<<` leftShift operator to append elements to a list:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=subscript_and_leftshift,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=subscript_and_leftshift,indent=0]
 ----
 <1> Access the first element of the list (zero-based counting)
 <2> Access the last element of the list with a negative index: -1 is the first element from the end of the list
@@ -1061,7 +1061,7 @@ As lists can be heterogeneous in nature, lists can also contain other lists to c
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=multi_dim_list,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=multi_dim_list,indent=0]
 ----
 <1> Define a list of list of numbers
 <2> Access the second element of the top-most list, and the first element of the inner list
@@ -1073,7 +1073,7 @@ you need to explicitely define the type of the array through coercion or type de
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=array_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=array_1,indent=0]
 ----
 <1> Define an array of strings using explicit variable type declaration
 <2> Assert that we created an array of strings
@@ -1084,7 +1084,7 @@ You can also create multi-dimensional arrays:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=array_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=array_2,indent=0]
 ----
 <1> You can define the bounds of a new array
 <2> Or declare an array without specifying its bounds
@@ -1093,7 +1093,7 @@ Access to elements of an array follows the same notation as for lists:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=array_3,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=array_3,indent=0]
 ----
 <1> Retrieve the first element of the array
 <2> Set the value of the third element of the array to a new value
@@ -1132,7 +1132,7 @@ and the whole keys and values surrounded by square brackets.
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=map_def_access,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=map_def_access,indent=0]
 ----
 <1> We define a map of string color names, associated with their hexadecimal-coded html colors
 <2> We use the subscript notation to check the content associated with the `red` key
@@ -1150,7 +1150,7 @@ If you try to access a key which is not present in the map:
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=unknown_key,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=unknown_key,indent=0]
 ----
 
 You will retrieve a `null` result.
@@ -1159,7 +1159,7 @@ In the examples above, we used string keys, but you can also use values of other
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=number_key,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=number_key,indent=0]
 ----
 
 Here, we used numbers as keys, as numbers can unambiguously be recognized as numbers,
@@ -1168,7 +1168,7 @@ But consider the case you want to pass a variable in lieu of the key, to have th
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=variable_key_1,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=variable_key_1,indent=0]
 ----
 <1> The `key` associated with the `'Guillaume'` name will actually be the `"key"` string, not the value associated with the `key` variable
 <2> The map doesn't contain the `'name'` key
@@ -1183,7 +1183,7 @@ When you need to pass variable values as keys in your map definitions, you must
 
 [source,groovy]
 ----
-include::{includedir}/../test/SyntaxTest.groovy[tags=variable_key_2,indent=0]
+include::{projectdir}/src/spec/test/SyntaxTest.groovy[tags=variable_key_2,indent=0]
 ----
 <1> This time, we surround the `key` variable with parentheses, to instruct the parser we are passing a variable rather than defining a string key
 <2> The map does contain the `name` key
diff --git a/src/spec/doc/core-testing-guide.adoc b/src/spec/doc/core-testing-guide.adoc
index d98e0a7..9dc16e0 100644
--- a/src/spec/doc/core-testing-guide.adoc
+++ b/src/spec/doc/core-testing-guide.adoc
@@ -125,7 +125,7 @@ By using maps or expandos, we can incorporate desired behaviour of a collaborato
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=map_coercion,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=map_coercion,indent=0]
 ----
 
 The `as` operator can be used to coerce a map to a particular class. The given map keys are interpreted as
@@ -151,7 +151,7 @@ Let's have an example on coercing a closure to be of a specific type:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=closure_coercion,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=closure_coercion,indent=0]
 ----
 
 Groovy supports a feature called implicit SAM coercion. This means that the `as` operator is not necessary in situations
@@ -160,7 +160,7 @@ classes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=sam_coercion,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=sam_coercion,indent=0]
 ----
 
 ==== MockFor and StubFor
@@ -178,14 +178,14 @@ Let's assume our target classes looked like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=collaborators,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=collaborators,indent=0]
 ----
 
 With `MockFor`, a mock expectation is always sequence dependent and its use automatically ends with a call to `verify`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=mockFor,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=mockFor,indent=0]
 ----
 <1> a new mock is created by a new instance of `MockFor`
 <2> a `Closure` is passed to `use` which enables the mocking functionality
@@ -202,7 +202,7 @@ In contrast to `MockFor` the stub expectation checked with `verify` is sequence
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=stubFor,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=stubFor,indent=0]
 ----
 <1> a new stub is created by a new instance of `StubFor`
 <2> the `with` method is used for delegating all calls inside the closure to the `StubFor` instance
@@ -224,7 +224,7 @@ JDK classes like for example `java.lang.String` as well:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=emc,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=emc,indent=0]
 ----
 
 The `ExpandoMetaClass` is a rather good candidate for mocking functionality as it allows for more advanced stuff
@@ -232,14 +232,14 @@ like mocking static methods
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=emc2,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=emc2,indent=0]
 ----
 
 or even constructors
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=emc3,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=emc3,indent=0]
 ----
 
 [NOTE]
@@ -254,7 +254,7 @@ replacing the meta-class in the `GroovyMetaClassRegistry`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=emc4,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=emc4,indent=0]
 ----
 
 Another alternative is to register a `MetaClassRegistryChangeEventListener`, track the changed classes and remove
@@ -267,7 +267,7 @@ level:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/MockingExampleTests.groovy[tags=emc5,indent=0]
+include::{projectdir}/src/spec/test/testingguide/MockingExampleTests.groovy[tags=emc5,indent=0]
 ----
 
 In this case the meta-class change is related to the instance only. Depending on the test scenario this might be a better
@@ -285,7 +285,7 @@ combinations from a list containing two or more sub-lists:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GDKMethodTests.groovy[tags=combinations,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GDKMethodTests.groovy[tags=combinations,indent=0]
 ----
 
 The method could be used in test case scenarios to generate all possible argument combinations for a specific method
@@ -301,7 +301,7 @@ It applies a function on each combination of the input lists:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GDKMethodTests.groovy[tags=each_combination,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GDKMethodTests.groovy[tags=each_combination,indent=0]
 ----
 
 The method could be used in the testing context to call methods with each of the generated combinations.
@@ -398,7 +398,7 @@ being available to be called in every test method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=assertions,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=assertions,indent=0]
 ----
 
 As can be seen above, in contrast to Java it is possible to leave out the parenthesis in most situations which
@@ -409,7 +409,7 @@ code string succeeds without any exception:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=assertScript,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=assertScript,indent=0]
 ----
 
 ==== shouldFail Methods
@@ -419,7 +419,7 @@ otherwise the assertion fails:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_without_class,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_without_class,indent=0]
 ----
 
 The example above uses the basic `shouldFail` method interface that takes a `groovy.lang.Closure` as a single argument.
@@ -430,7 +430,7 @@ implementation that takes the `Exception` class as first argument and the `Closu
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_with_class,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_with_class,indent=0]
 ----
 
 If anything other than `IndexOutOfBoundsException` (or a descendant class of it) is thrown, the test case will fail.
@@ -440,7 +440,7 @@ useful if you want to assert on the exception error message:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_with_msg,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=should_fail_with_msg,indent=0]
 ----
 
 ==== notYetImplemented Method
@@ -450,7 +450,7 @@ as not yet implemented. As long as the test method fails and is marked with `not
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=not_yet_implemented,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=not_yet_implemented,indent=0]
 ----
 <1> a call to `notYetImplemented` is necessary for `GroovyTestCase` to get the current method stack.
 <2> as long as the test evaluates to `false` the test execution will be successful.
@@ -461,7 +461,7 @@ for the `notYetImplemented` method call:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/GroovyTestCaseExampleTests.groovy[tags=not_yet_implemented_ast,indent=0]
+include::{projectdir}/src/spec/test/testingguide/GroovyTestCaseExampleTests.groovy[tags=not_yet_implemented_ast,indent=0]
 ----
 
 === JUnit 4
@@ -471,7 +471,7 @@ various static methods that can be used as replacement for the `GroovyTestCase`
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/JUnit4ExampleTests.groovy[tags=junit4_example,indent=0]
+include::{projectdir}/src/spec/test/testingguide/JUnit4ExampleTests.groovy[tags=junit4_example,indent=0]
 ----
 
 As can be seen in the example above, the static methods found in `GroovyAssert` are imported at the beginning of the
@@ -489,10 +489,10 @@ exception:
 
 [source,groovy]
 ----
-include::{includedir}/../test/testingguide/JUnit4ExampleTests.groovy[tags=should_fail_return,indent=0]
+include::{projectdir}/src/spec/test/testingguide/JUnit4ExampleTests.groovy[tags=should_fail_return,indent=0]
 ----
 
-include::{rootProjectDir}/subprojects/groovy-test-junit5/{specfolder}/fragment_testing-with-junit5.adoc[leveloffset=+1]
+include::{rootProjectDir}/subprojects/groovy-test-junit5/src/spec/doc/testing-with-junit5.adoc[leveloffset=+1]
 
 == Testing with Spock
 
diff --git a/src/spec/doc/fragment_traits.adoc b/src/spec/doc/core-traits.adoc
similarity index 80%
rename from src/spec/doc/fragment_traits.adoc
rename to src/spec/doc/core-traits.adoc
index 7d00fd0..624bd9e 100644
--- a/src/spec/doc/fragment_traits.adoc
+++ b/src/spec/doc/core-traits.adoc
@@ -33,7 +33,7 @@ They can be seen as *interfaces* carrying both *default implementations* and *st
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
 ----
 <1> declaration of a trait
 <2> declaration of a method inside a trait
@@ -42,7 +42,7 @@ Then it can be used like a normal interface using the `implements` keyword:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=bird,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=bird,indent=0]
 ----
 <1> Adds the trait `FlyingAbility` to the `Bird` class capabilities
 <2> instantiate a new `Bird`
@@ -57,7 +57,7 @@ Declaring a method in a trait can be done like any regular method in a class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
 ----
 <1> declaration of a trait
 <2> declaration of a method inside a trait
@@ -68,7 +68,7 @@ In addition, traits may declare _abstract_ methods too, which therefore need to
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=greetable,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=greetable,indent=0]
 ----
 <1> implementing class will have to declare the `name` method
 <2> can be mixed with a concrete method
@@ -77,7 +77,7 @@ Then the trait can be used like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=greetable_person,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=greetable_person,indent=0]
 ----
 <1> implement the trait `Greetable`
 <2> since `name` was abstract, it is required to implement it
@@ -89,7 +89,7 @@ Traits may also define private methods. Those methods will not appear in the tra
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=private_method_in_trait,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=private_method_in_trait,indent=0]
 ----
 <1> define a private method `greetingMessage` in the trait
 <2> the public `greet` message calls `greetingMessage` by default
@@ -118,21 +118,21 @@ want trait implementation methods that can't be overridden.
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=meaningofthis_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=meaningofthis_header,indent=0]
 ----
 
 then calling:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=meaningofthis_snippet,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=meaningofthis_snippet,indent=0]
 ----
 
 will return the same instance:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=meaningofthis_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=meaningofthis_assert,indent=0]
 ----
 
 == Interfaces
@@ -141,7 +141,7 @@ Traits may implement interfaces, in which case the interfaces are declared using
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_implementing_interface,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_implementing_interface,indent=0]
 ----
 <1> declaration of a normal interface
 <2> add `Named` to the list of implemented interfaces
@@ -157,7 +157,7 @@ A trait may define properties, like in the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_with_property,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_with_property,indent=0]
 ----
 <1> declare a property `name` inside a trait
 <2> declare a class which implements the trait
@@ -173,7 +173,7 @@ will let you do that:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_with_private_field,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_with_private_field,indent=0]
 ----
 <1> declare a private field `count` inside a trait
 <2> declare a public method `count` that increments the counter and returns it
@@ -191,7 +191,7 @@ field names are remapped in the implementing class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_with_public_field,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_with_public_field,indent=0]
 ----
 <1> declare a public *field* inside the trait
 <2> declare a class implementing the trait
@@ -215,15 +215,15 @@ Traits can be used to implement multiple inheritance in a controlled way. For ex
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=speaking_simple,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=flying_simple,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=speaking_simple,indent=0]
 ----
 
 And a class implementing both traits:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=speakingduck,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=speakingduck,indent=0]
 ----
 <1> the `Duck` class implements both `FlyingAbility` and `SpeakingAbility`
 <2> creates a new instance of `Duck`
@@ -239,7 +239,7 @@ can slightly change the example above, by having a duck which quacks:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=quackingduck,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=quackingduck,indent=0]
 ----
 <1> define a method specific to `Duck`, named `quack`
 <2> override the default implementation of `speak` so that we use `quack` instead
@@ -253,7 +253,7 @@ Traits may extend another trait, in which case you must use the `extends` keywor
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_inherit,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_inherit,indent=0]
 -----
 <1> the `Named` trait defines a single `name` property
 <2> the `Polite` trait *extends* the `Named` trait
@@ -268,7 +268,7 @@ clause:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=trait_multiple_inherit,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=trait_multiple_inherit,indent=0]
 ----
 <1> `WithId` trait defines the `id` property
 <2> `WithName` trait defines the `name` property
@@ -282,7 +282,7 @@ This means that traits are fully compatible with duck typing:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=ducktyping,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=ducktyping,indent=0]
 ----
 <1> the `SpeakingDuck` expects the `quack` method to be defined
 <2> the `Duck` class does implement the method using _methodMissing_
@@ -295,7 +295,7 @@ will inherit the behavior from the trait, like in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=dynamicobject,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=dynamicobject,indent=0]
 ----
 <1> create a trait implementing several MOP methods
 <2> the `Dynamic` class defines a property
@@ -315,7 +315,7 @@ method in another trait, we have a conflict:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default,indent=0]
 -----
 <1> trait `A` defines a method named `exec` returning a `String`
 <2> trait `B` defines the very same method
@@ -326,7 +326,7 @@ Here, `B` is declared after `A` so the method from `B` will be picked up:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=multiple_inherit_default_assert,indent=0]
 ----
 
 === User conflict resolution
@@ -336,7 +336,7 @@ In the example above, we can ensure the method from trait A is invoked by writin
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=multiple_inherit_user,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=multiple_inherit_user,indent=0]
 ----
 <1> explicit call of `exec` from the trait `A`
 <2> calls the version from `A` instead of using the default resolution, which would be the one from `B`
@@ -348,7 +348,7 @@ trait. As an example, let's start with this trait and the following class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=runtime_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=runtime_header,indent=0]
 ----
 <1> the `Extra` trait defines an `extra` method
 <2> the `Something` class does *not* implement the `Extra` trait
@@ -358,7 +358,7 @@ Then if we do:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=runtime_fail,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=runtime_fail,indent=0]
 ----
 
 the call to extra would fail because `Something` is not implementing `Extra`. It is possible to do it at runtime with
@@ -366,7 +366,7 @@ the following syntax:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=runtime_success,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=runtime_success,indent=0]
 ----
 <1> use of the *as* keyword to coerce an object to a trait *at runtime*
 <2> then `extra` can be called on the object
@@ -382,9 +382,9 @@ Should you need to implement several traits at once, you can use the `withTraits
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=withtraits_header,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=withtraits_fail,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=withtraits_success,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=withtraits_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=withtraits_fail,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=withtraits_success,indent=0]
 ----
 <1> call to `methodFromA` will fail because `C` doesn't implement `A`
 <2> call to `methodFromB` will fail because `C` doesn't implement `B`
@@ -403,7 +403,7 @@ is not capable of handling a message. To illustrate this, let's imagine a messag
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=messagehandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=messagehandler,indent=0]
 -----
 
 Then you can compose a message handler by applying small behaviors. For example, let's define a default handler in the
@@ -411,21 +411,21 @@ form of a trait:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=defaulthandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=defaulthandler,indent=0]
 -----
 
 Then any class can inherit the behavior of the default handler by implementing the trait:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=simplehandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=simplehandler,indent=0]
 -----
 
 Now what if you want to log all messages, in addition to the default handler? One option is to write this:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=simplehandlerwithlogging,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=simplehandlerwithlogging,indent=0]
 -----
 <1> explicitly implement the `on` method
 <2> perform logging
@@ -440,7 +440,7 @@ As an alternative, we can write another trait which responsibility is limited to
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=logginghandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=logginghandler,indent=0]
 -----
 <1> the logging handler is itself a handler
 <2> prints the message it receives
@@ -450,14 +450,14 @@ Then our class can be rewritten as this:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=handlerwithlogger,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert,indent=0]
 -----
 
 which will print:
 
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert_output,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=handlerwithlogger_assert_output,indent=0]
 ----
 
 As the priority rules imply that `LoggerHandler` wins because it is declared last, then a call to `on` will use
@@ -469,7 +469,7 @@ that start with `say`:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=sayhandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=sayhandler,indent=0]
 -----
 <1> a handler specific precondition
 <2> if the precondition is not met, pass the message to the next handler in the chain
@@ -478,8 +478,8 @@ Then our final handler looks like this:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=implementinghandler,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=implementinghandler_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=implementinghandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=implementinghandler_assert,indent=0]
 -----
 
 Which means:
@@ -493,21 +493,21 @@ This approach is very powerful because it allows you to write handlers that do n
 combine them in the order you want. For example, if we execute the code, it will print:
 
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=implementinghandler_output,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=implementinghandler_output,indent=0]
 ----
 
 but if we move the logging handler to be the second one in the chain, the output is different:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=alternatehandler,indent=0]
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=alternatehandler_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=alternatehandler,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=alternatehandler_assert,indent=0]
 ----
 
 prints:
 
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=alternatehandler_output,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=alternatehandler_output,indent=0]
 ----
 
 The reason is that now, since the `SayHandler` consumes the message without calling `super`, the logging handler is
@@ -524,7 +524,7 @@ For example, it is possible to decorate final classes thanks to this behavior:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=decoratefinalclass,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=decoratefinalclass,indent=0]
 ----
 <1> define a trait named `Filtering`, supposed to be applied on a `StringBuilder` at runtime
 <2> redefine the `append` method
@@ -547,7 +547,7 @@ imagine the following trait:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=sam_trait,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=sam_trait,indent=0]
 ----
 <1> the `greet` method is not abstract and calls the abstract method `getName`
 <2> `getName` is an abstract method
@@ -556,7 +556,7 @@ Since `getName` is the _single abstract method_ in the `Greeter` trait, you can
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=sam_trait_assignment,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=sam_trait_assignment,indent=0]
 ----
 <1> the closure "becomes" the implementation of the `getName` single abstract method
 
@@ -564,7 +564,7 @@ or even:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=sam_trait_method,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=sam_trait_method,indent=0]
 ----
 <1> the greet method accepts the SAM type Greeter as parameter
 <2> we can call it directly with a closure
@@ -583,7 +583,7 @@ To illustrate the concept, let's start with this simple example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=forceoverride_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=forceoverride_header,indent=0]
 ----
 
 In this example, we create a simple test case which uses two properties (_config_ and _shell_) and uses those in
@@ -592,7 +592,7 @@ One option is to create a subclass of `SomeTest`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=forceoverride_extends,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=forceoverride_extends,indent=0]
 ----
 
 It works, but what if you have actually multiple test classes, and that you want to test the new configuration for all
@@ -600,21 +600,21 @@ those test classes? Then you would have to create a distinct subclass for each t
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=forceoverride_extends2,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=forceoverride_extends2,indent=0]
 ----
 
 Then what you see is that the `setup` method of both tests is the same. The idea, then, is to create a trait:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=forceoverride_trait,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=forceoverride_trait,indent=0]
 ----
 
 Then use it in the subclasses:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=forceoverride_miss_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=forceoverride_miss_header,indent=0]
 ...
 ----
 
@@ -633,7 +633,7 @@ object:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=runtime_forceoverride,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=runtime_forceoverride,indent=0]
 ----
 <1> the `Person` class defines a `name` property which results in a `getName` method
 <2> `Bob` is a trait which defines `getName` as returning `Bob`
@@ -660,7 +660,7 @@ Methods added through a mixin are, on the contrary, only visible at runtime:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=diff_mixin,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=diff_mixin,indent=0]
 ----
 <1> class `A` defines `methodFromA`
 <2> class `B` defines `methodFromB`
@@ -697,7 +697,7 @@ Let's start with a simple example:
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=staticfield_header,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=staticfield_header,indent=0]
 -----
 <1> the static field is declared in the trait
 <2> a static method is also declared in the trait
@@ -709,14 +709,14 @@ As usual, it is not recommended to use public fields. Anyway, should you want th
 
 [source,groovy]
 -----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=staticfield_notontrait,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=staticfield_notontrait,indent=0]
 -----
 
 because there is _no_ static field _CALLED_ defined on the trait itself. Likewise, if you have two distinct implementing classes, each one gets a distinct static field:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=staticfield_distinct,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=staticfield_distinct,indent=0]
 ----
 <1> class `Bar` implements the trait
 <2> class `Baz` also implements the trait
@@ -731,7 +731,7 @@ a per-trait basis. So consider the following example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=intcouple,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=intcouple,indent=0]
 ----
 
 
@@ -739,14 +739,14 @@ The trait defines two properties, `x` and `y`, as well as a `sum` method. Now le
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=intcouple_impl,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=intcouple_impl,indent=0]
 ----
 
 The result of calling `f` is `3`, because `f` delegates to `sum` in the trait, which has state. But what if we write this instead?
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override,indent=0]
 ----
 <1> Override property `x`
 <2> Override property `y`
@@ -756,7 +756,7 @@ If you call `elem.f()`, what is the expected output? Actually it is:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_assert,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_assert,indent=0]
 ----
 
 The reason is that the `sum` method accesses the _fields_ of the trait. So it is using the `x` and `y` values defined
@@ -765,7 +765,7 @@ getters and setters, like in this last example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_directgetter,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=intcouple_impl_override_directgetter,indent=0]
 ----
 
 == Self types
@@ -777,7 +777,7 @@ To illustrate this, let's start with this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=selftype_intro,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=selftype_intro,indent=0]
 ----
 <1> A `Service` class, beyond your control (in a library, ...) defines a `sendMessage` method
 <2> A `Device` class, beyond your control (in a library, ...)
@@ -800,7 +800,7 @@ requires `this` as a parameter, and actually requires it to be a `Device`?
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=selftype_securityservice,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=selftype_securityservice,indent=0]
 ----
 
 If you want to be able to call `this` in the trait, then you will explicitly need to cast `this` into a `Device`. This can
@@ -819,14 +819,14 @@ So in our previous example, we can fix the trait using the `@groovy.transform.Se
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=selftype_fixed,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=selftype_fixed,indent=0]
 ----
 
 Now if you try to implement this trait on a class that is *not* a device, a compile-time error will occur:
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=selftype_compiletimeerror,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=selftype_compiletimeerror,indent=0]
 ----
 
 The error will be:
@@ -852,7 +852,7 @@ Within traits, prefix and postfix operations are not allowed if they update a fi
 
 [source,groovy]
 ----
-include::{includedir}/../test/TraitsSpecificationTest.groovy[tags=prefix_postfix,indent=0]
+include::{projectdir}/src/spec/test/TraitsSpecificationTest.groovy[tags=prefix_postfix,indent=0]
 ----
 <1> `x` is defined within the trait, postfix increment is not allowed
 <2> `x` is defined within the trait, prefix decrement is not allowed
diff --git a/src/spec/doc/fragment_design-pattern-abstract-factory.adoc b/src/spec/doc/design-pattern-abstract-factory.adoc
similarity index 90%
rename from src/spec/doc/fragment_design-pattern-abstract-factory.adoc
rename to src/spec/doc/design-pattern-abstract-factory.adoc
index d2e6540..6d189f3 100644
--- a/src/spec/doc/fragment_design-pattern-abstract-factory.adoc
+++ b/src/spec/doc/design-pattern-abstract-factory.adoc
@@ -35,21 +35,21 @@ First let's look at the game-specific code for a http://en.wikipedia.org/wiki/Tw
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=abstract_factory_example1,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=abstract_factory_example1,indent=0]
 ----
 
 Now, let's look at the game-specific code for a number guessing game:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=abstract_factory_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=abstract_factory_example2,indent=0]
 ----
 
 Now, let's write our factory code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=abstract_factory_code,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=abstract_factory_code,indent=0]
 ----
 
 The important aspect of this factory is that it allows selection of an entire family of concrete classes.
@@ -58,7 +58,7 @@ Here is how we would use the factory:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=abstract_factory_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=abstract_factory_usage,indent=0]
 ----
 
 Note that the first line configures which family of concrete game classes we will use. It's not important that we selected which family to use by using the factory property as shown in the first line. Other ways would be equally valid examples of this pattern. For example, we may have asked the user which game they wanted to play or determined which game from an environment setting.
diff --git a/src/spec/doc/fragment_design-pattern-adapter.adoc b/src/spec/doc/design-pattern-adapter.adoc
similarity index 71%
rename from src/spec/doc/fragment_design-pattern-adapter.adoc
rename to src/spec/doc/design-pattern-adapter.adoc
index a754279..0eb2c21 100644
--- a/src/spec/doc/fragment_design-pattern-adapter.adoc
+++ b/src/spec/doc/design-pattern-adapter.adoc
@@ -21,7 +21,7 @@
 
 = Adapter Pattern
 
-The https://en.wikipedia.org/wiki/Adapter_pattern[Adapter Pattern] (sometimes called the wrapper pattern) allows objects satisfying one interface to be used where another type of interface is expected. There are two typical flavours of the pattern: the __delegation__ flavour and the __inheritance__ flavour.
+The http://en.wikipedia.org/wiki/Adapter_pattern[Adapter Pattern] (sometimes called the wrapper pattern) allows objects satisfying one interface to be used where another type of interface is expected. There are two typical flavours of the pattern: the __delegation__ flavour and the __inheritance__ flavour.
 
 == Delegation Example
 
@@ -29,7 +29,7 @@ Suppose we have the following classes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_delegation_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_delegation_classes,indent=0]
 ----
 
 We can ask the `RoundHole` class if a `RoundPeg` fits in it, but if we ask the same question for a `SquarePeg`, then it will fail because the `SquarePeg` class doesn't have a `radius` property (i.e. doesn't satisfy the required interface).
@@ -38,14 +38,14 @@ To get around this problem, we can create an adapter to make it appear to have t
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_delegation_code,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_delegation_code,indent=0]
 ----
 
 We can use the adapter like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_delegation_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_delegation_usage,indent=0]
 ----
 
 Which results in the following output:
@@ -63,21 +63,21 @@ Let's consider the same example again using inheritance. First, here are the ori
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_inheritance_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_inheritance_classes,indent=0]
 ----
 
 An adapter using inheritance:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_inheritance_code,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_inheritance_code,indent=0]
 ----
 
 Using the adapter:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_inheritance_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_inheritance_usage,indent=0]
 ----
 
 The output:
@@ -95,21 +95,21 @@ As a variation of the previous examples, we could instead define the following i
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_closure_interface,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_closure_interface,indent=0]
 ----
 
 We can then define an adapter as a closure as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_closure_define,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_closure_define,indent=0]
 ----
 
 And use it like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_closure_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_closure_usage,indent=0]
 ----
 
 == Adapting using the ExpandoMetaClass
@@ -120,7 +120,7 @@ Here is how the example would work using that feature:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=adapter_expando_meta_class,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=adapter_expando_meta_class,indent=0]
 ----
 
 After you create a peg object, you can simply add a property to it on the fly. No need to change the original class and no need for an adapter class.
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-bouncer.adoc b/src/spec/doc/design-pattern-bouncer.adoc
similarity index 77%
rename from src/spec/doc/fragment_design-pattern-bouncer.adoc
rename to src/spec/doc/design-pattern-bouncer.adoc
index 404dcf4..3aaf70f 100644
--- a/src/spec/doc/fragment_design-pattern-bouncer.adoc
+++ b/src/spec/doc/design-pattern-bouncer.adoc
@@ -33,21 +33,21 @@ We might have a utility method such as:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_null_check,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_null_check,indent=0]
 ----
 
 And we would use it like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage,indent=0]
 ----
 
 But a more Groovy way to do this would simply be like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage_groovy_way,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_null_check_usage_groovy_way,indent=0]
 ----
 
 == Validation Example
@@ -56,19 +56,19 @@ As an alternative example, we might have this utility method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_validation,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_validation,indent=0]
 ----
 
 And we would use it like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_validation_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_validation_usage,indent=0]
 ----
 
 But with Groovy we could just as easily use:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=bouncer_validation_usage_groovy_way,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=bouncer_validation_usage_groovy_way,indent=0]
 ----
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-chain-of-responsibility.adoc b/src/spec/doc/design-pattern-chain-of-responsibility.adoc
similarity index 95%
rename from src/spec/doc/fragment_design-pattern-chain-of-responsibility.adoc
rename to src/spec/doc/design-pattern-chain-of-responsibility.adoc
index 977dee1..cf1206d 100644
--- a/src/spec/doc/fragment_design-pattern-chain-of-responsibility.adoc
+++ b/src/spec/doc/design-pattern-chain-of-responsibility.adoc
@@ -29,7 +29,7 @@ In this example, the script sends requests to the `lister` object. The `lister`
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=chain_of_responsibility,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=chain_of_responsibility,indent=0]
 ----
 
 The output will be a list of files (with slightly different format depending on the operating system).
diff --git a/src/spec/doc/fragment_design-pattern-composite.adoc b/src/spec/doc/design-pattern-composite.adoc
similarity index 74%
rename from src/spec/doc/fragment_design-pattern-composite.adoc
rename to src/spec/doc/design-pattern-composite.adoc
index 24e33ca..32ce50e 100644
--- a/src/spec/doc/fragment_design-pattern-composite.adoc
+++ b/src/spec/doc/design-pattern-composite.adoc
@@ -21,7 +21,7 @@
 
 = Composite Pattern
 
-The https://en.wikipedia.org/wiki/Composite_pattern[Composite Pattern] allows you to treat single instances of an object the same way as a group of objects. The pattern is often used with hierarchies of objects. Typically, one or more methods should be callable in the same way for either __leaf__ or __composite__ nodes within the hierarchy. In such a case, composite nodes typically invoke the same named method for each of their children nodes.
+The http://en.wikipedia.org/wiki/Composite_pattern[Composite Pattern] allows you to treat single instances of an object the same way as a group of objects. The pattern is often used with hierarchies of objects. Typically, one or more methods should be callable in the same way for either __leaf__ or __composite__ nodes within the hierarchy. In such a case, composite nodes typically invoke the same named method for each of their children nodes.
 
 == Example
 
@@ -39,7 +39,7 @@ Here is the code:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=composite_code,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=composite_code,indent=0]
 ----
 
 Here is the resulting output:
diff --git a/src/spec/doc/fragment_design-pattern-decorator.adoc b/src/spec/doc/design-pattern-decorator.adoc
similarity index 77%
rename from src/spec/doc/fragment_design-pattern-decorator.adoc
rename to src/spec/doc/design-pattern-decorator.adoc
index cd97505..d676d0f 100644
--- a/src/spec/doc/fragment_design-pattern-decorator.adoc
+++ b/src/spec/doc/design-pattern-decorator.adoc
@@ -21,7 +21,7 @@
 
 = Decorator Pattern
 
-The https://en.wikipedia.org/wiki/Decorator_pattern[Decorator Pattern] provides a mechanism to embellish the behaviour of an object without changing its essential interface. A decorated object should be able to be substituted wherever the original (non-decorated) object was expected. Decoration typically does not involve modifying the source code of the original object and decorators should be able to be combined in flexible ways to produce objects with several embellishments.
+The http://en.wikipedia.org/wiki/Decorator_pattern[Decorator Pattern] provides a mechanism to embellish the behaviour of an object without changing its essential interface. A decorated object should be able to be substituted wherever the original (non-decorated) object was expected. Decoration typically does not involve modifying the source code of the original object and decorators should be able to be combined in flexible ways to produce objects with several embellishments.
 
 == Traditional Example
 
@@ -29,7 +29,7 @@ Suppose we have the following `Logger` class.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_logger_class,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_logger_class,indent=0]
 ----
 
 There might be times when it is useful to timestamp a log message, or times when we might want to change the case of the message. We could try to build all of this functionality into our `Logger` class. If we did that, the `Logger` class would start to be very complex. Also, everyone would obtain all of features even when they might not want a small subset of the features. Finally, feature interaction would become quite difficult to control.
@@ -38,21 +38,21 @@ To overcome these drawbacks, we instead define two decorator classes. Uses of th
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_traditional_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_traditional_classes,indent=0]
 ----
 
 We can use the decorators like so:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_traditional_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_traditional_usage,indent=0]
 ----
 
 You can see that we embellish the logger behaviour with both decorators. Because of the order we chose to apply the decorators, our log message comes out capitalised and the timestamp is in normal case. If we swap the order around, let's see what happens:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_traditional_usage2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_traditional_usage2,indent=0]
 ----
 
 Now the timestamp itself has also been changed to be uppercase.
@@ -63,14 +63,14 @@ Our previous decorators were specific to `Logger` objects. We can use Groovy's M
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_class,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_class,indent=0]
 ----
 
 It takes any class and decorates it so that any `String` method parameter will automatically be changed to lower case.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_dynamic_behaviour_usage,indent=0]
 ----
 
 Just be careful with ordering here. The original decorators were restricted to decorating `Logger` objects. This decorator works with any object type, so we can't swap the ordering around, i.e. this won't work:
@@ -90,7 +90,7 @@ Here's what the code looks like:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_runtime_behaviour,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_runtime_behaviour,indent=0]
 ----
 
 This achieves a similar result to applying a single decorator but we have no way to easily apply and remove embellishments on the fly.
@@ -101,21 +101,21 @@ Suppose we have a calculator class (Actually any class would do).
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_calc_class,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_calc_class,indent=0]
 ----
 
 We might be interested in observing usage of the class over time. If it is buried deep within our codebase, it might be hard to determine when it is being called and with what parameters. Also, it might be hard to know if it is performing well. We can easily make a generic tracing decorator that prints out tracing information whenever any method on the `Calc` class is called and also provide timing information about how long it took to execute. Here is the code for the tracing decorator:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator,indent=0]
 ----
 
 Here is how to use the class in a script:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_tracing_decorator_usage,indent=0]
 ----
 
 And here is what you would see after running this script:
@@ -133,14 +133,14 @@ Groovy even comes with a built-in `TracingInterceptor`. We can extend the built-
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_interceptor,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_interceptor,indent=0]
 ----
 
 Here is an example of using this new class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_interceptor_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_interceptor_usage,indent=0]
 ----
 
 And here is the output:
@@ -160,7 +160,7 @@ If you are trying to decorate an object (i.e. just a particular instance of the
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_reflect_proxy,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_reflect_proxy,indent=0]
 ----
 
 If there were many methods to intercept, then this approach could be modified to look up closure in a map by method name and invoke it.
@@ -175,14 +175,14 @@ Here's the interface:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_spring_calc,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_spring_calc,indent=0]
 ----
 
 Here's the class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_spring_calc_impl,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_spring_calc_impl,indent=0]
 ----
 
 Now, we define our wiring in a file called `beans.xml` as follows:
@@ -213,7 +213,7 @@ Now, our script looks like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_spring_context,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_spring_context,indent=0]
 ----
 
 And when we run it, we see the results:
@@ -232,5 +232,5 @@ These days, you'll see this style used with async functions in JavaScript.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=decorator_gpars,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=decorator_gpars,indent=0]
 ----
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-delegation.adoc b/src/spec/doc/design-pattern-delegation.adoc
similarity index 72%
rename from src/spec/doc/fragment_design-pattern-delegation.adoc
rename to src/spec/doc/design-pattern-delegation.adoc
index 28c0ed9..6e0dc97 100644
--- a/src/spec/doc/fragment_design-pattern-delegation.adoc
+++ b/src/spec/doc/design-pattern-delegation.adoc
@@ -21,9 +21,9 @@
 
 = Delegation Pattern
 
-The https://en.wikipedia.org/wiki/Delegation_pattern[Delegation Pattern] is a technique where an object's behavior (public methods) is implemented by delegating responsibility to one or more associated objects.
+The http://en.wikipedia.org/wiki/Delegation_pattern[Delegation Pattern] is a technique where an object's behavior (public methods) is implemented by delegating responsibility to one or more associated objects.
 
-Groovy allows the traditional style of applying the delegation pattern, e.g. see https://refactoring.com/catalog/replaceSuperclassWithDelegate.html[Replace Inheritance with Delegation].
+Groovy allows the traditional style of applying the delegation pattern, e.g. see <<_replace_inheritance_with_delegation,Replace Inheritance with Delegation>>.
 
 == Implement Delegation Pattern using ExpandoMetaClass
 
@@ -33,21 +33,21 @@ Consider the following library class:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_delegator,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_delegator,indent=0]
 ----
 
 With this in your classpath, you can now apply the delegation pattern dynamically as shown in the following examples. First, consider we have the following classes:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_classes,indent=0]
 ----
 
 We can now use the __delegator__ to automatically borrow methods from the __lender__ object to extend the __Person__ class. We can borrow the methods as is or with a rename:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_usage,indent=0]
 ----
 
 The first line above, adds the __borrowFor__ method to the __Person__ class by delegating to the __lender__ object. The second line adds a __getMoney__ method to the __Person__ class by delegating to the __lender__ object's __borrowAmount__ method.
@@ -56,7 +56,7 @@ Alternatively, we could borrow multiple methods like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_usage2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_usage2,indent=0]
 ----
 
 Which adds these two methods to the __Person__ class.
@@ -65,7 +65,7 @@ Or if we want all the methods, like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_usage3,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_usage3,indent=0]
 ----
 
 Which will make all the methods in the delegate object available in the __Person__ class.
@@ -74,7 +74,7 @@ Alternatively, we can use a map notation to rename multiple methods:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_usage4,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_usage4,indent=0]
 ----
 
 == Implement Delegation Pattern using @Delegate annotation
@@ -85,5 +85,5 @@ This make delegation even easier:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=delegation_annotation,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=delegation_annotation,indent=0]
 ----
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-flyweight.adoc b/src/spec/doc/design-pattern-flyweight.adoc
similarity index 91%
rename from src/spec/doc/fragment_design-pattern-flyweight.adoc
rename to src/spec/doc/design-pattern-flyweight.adoc
index cfcd39f..e07a8c1 100644
--- a/src/spec/doc/fragment_design-pattern-flyweight.adoc
+++ b/src/spec/doc/design-pattern-flyweight.adoc
@@ -32,14 +32,14 @@ First we are going to model some complex aircraft (the first being a hoax compet
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=flyweight_boeing797,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_boeing797,indent=0]
 ----
 
 image::assets/img/b797-hoax.jpg[]
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=flyweight_airbus380,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_airbus380,indent=0]
 ----
 
 image::assets/img/a380.jpg[]
@@ -48,7 +48,7 @@ If we want to model our fleet, our first attempt might involve using many instan
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=flyweight_factory,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=flyweight_factory,indent=0]
 ----
 
 So here, even if our fleet contained hundreds of planes, we would only have one heavy-weight object for each type of aircraft.
diff --git a/src/spec/doc/design-patterns-in-groovy.adoc b/src/spec/doc/design-pattern-in-groovy.adoc
similarity index 61%
rename from src/spec/doc/design-patterns-in-groovy.adoc
rename to src/spec/doc/design-pattern-in-groovy.adoc
index 576ad12..6d7d257 100644
--- a/src/spec/doc/design-patterns-in-groovy.adoc
+++ b/src/spec/doc/design-pattern-in-groovy.adoc
@@ -22,8 +22,7 @@
 = Design patterns in Groovy
 
 
-Using https://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29[design patterns] with Java is a well-established topic.
-Design patterns also apply to Groovy:
+Using http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29[design patterns] with Java is a well-established topic. Design patterns also apply to Groovy:
 
 * some patterns carry over directly (and can make use of normal Groovy syntax improvements for greater readability)
 * some patterns are no longer required because they are built right into the language or because Groovy supports a better way of achieving the intent of the pattern
@@ -31,41 +30,41 @@ Design patterns also apply to Groovy:
 
 == Patterns
 
-include::{includedir}/fragment_design-pattern-abstract-factory.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-abstract-factory.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-adapter.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-adapter.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-bouncer.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-bouncer.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-chain-of-responsibility.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-chain-of-responsibility.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-composite.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-composite.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-decorator.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-decorator.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-delegation.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-delegation.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-flyweight.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-flyweight.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-iterator.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-iterator.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-loan-my-resource.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-loan-my-resource.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-null-object.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-null-object.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-pimp-my-library.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-pimp-my-library.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-proxy.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-proxy.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-singleton.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-singleton.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-state.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-state.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-strategy.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-strategy.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-template-method.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-template-method.adoc[leveloffset=+2]
 
-include::{includedir}/fragment_design-pattern-visitor.adoc[leveloffset=+2]
+include::{projectdir}/{specfolder}/design-pattern-visitor.adoc[leveloffset=+2]
 
 == References
 
diff --git a/src/spec/doc/fragment_design-pattern-iterator.adoc b/src/spec/doc/design-pattern-iterator.adoc
similarity index 78%
rename from src/spec/doc/fragment_design-pattern-iterator.adoc
rename to src/spec/doc/design-pattern-iterator.adoc
index d9d6857..f17bb3d 100644
--- a/src/spec/doc/fragment_design-pattern-iterator.adoc
+++ b/src/spec/doc/design-pattern-iterator.adoc
@@ -22,7 +22,7 @@
 = Iterator Pattern
 
 
-The https://en.wikipedia.org/wiki/Iterator_pattern[Iterator Pattern] allows sequential access to the elements of an aggregate object without exposing its underlying representation.
+The http://en.wikipedia.org/wiki/Iterator_pattern[Iterator Pattern] allows sequential access to the elements of an aggregate object without exposing its underlying representation.
 
 Groovy has the iterator pattern built right in to many of its closure operators, e.g. `each` and `eachWithIndex` as well as the `for .. in` loop.
 
@@ -30,7 +30,7 @@ For example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=iterator_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=iterator_example,indent=0]
 ----
 
 Results in the output:
@@ -51,7 +51,7 @@ Another example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=iterator_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=iterator_example2,indent=0]
 ----
 
 Results in:
diff --git a/src/spec/doc/fragment_design-pattern-loan-my-resource.adoc b/src/spec/doc/design-pattern-loan-my-resource.adoc
similarity index 84%
rename from src/spec/doc/fragment_design-pattern-loan-my-resource.adoc
rename to src/spec/doc/design-pattern-loan-my-resource.adoc
index b612051..f443d35 100644
--- a/src/spec/doc/fragment_design-pattern-loan-my-resource.adoc
+++ b/src/spec/doc/design-pattern-loan-my-resource.adoc
@@ -32,14 +32,14 @@ Consider the following code which works with a file. First we might write some l
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=loan_my_resource_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=loan_my_resource_example,indent=0]
 ----
 
 We could also read back the contents of the file a line at a time and print each line out:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=loan_my_resource_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=loan_my_resource_example2,indent=0]
 ----
 
 Note that normal Java `Reader` and `PrintWriter` objects were used under the covers by Groovy but the code writer did not have to worry about explicitly creating or closing those resources. The built-in Groovy methods loan the respective reader or writer to the closure code and then tidy up after themselves. So, you are using this pattern without having to do any work.
@@ -50,7 +50,7 @@ Consider how you might process the list of words on each line within the file. W
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=loan_my_resource_example3,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=loan_my_resource_example3,indent=0]
 ----
 
 Notice that we now have an explicit call to `close()` in our code. If we didn't code it just right (here we didn't surround the code in a ``try ... finally`` block, we run the risk of leaving the file handle open.
@@ -59,14 +59,14 @@ Let's now apply the loan pattern. First, we'll write a helper method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=loan_my_resource_example4,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=loan_my_resource_example4,indent=0]
 ----
 
 Now, we can re-write our code as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=loan_my_resource_example5,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=loan_my_resource_example5,indent=0]
 ----
 
 This is much simpler and has removed the explicit `close()`. This is now catered for in one spot so we can apply the appropriate level of testing or reviewing in just one spot to be sure we have no problems.
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-null-object.adoc b/src/spec/doc/design-pattern-null-object.adoc
similarity index 84%
rename from src/spec/doc/fragment_design-pattern-null-object.adoc
rename to src/spec/doc/design-pattern-null-object.adoc
index 342c84e..ee9c12d 100644
--- a/src/spec/doc/fragment_design-pattern-null-object.adoc
+++ b/src/spec/doc/design-pattern-null-object.adoc
@@ -30,14 +30,14 @@ Suppose we have the following system:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_simple_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_simple_example,indent=0]
 ----
 
 When run, this prints out `1200`. Suppose now that we now invoke:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_simple_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_simple_example2,indent=0]
 ----
 
 If we now try to calculate `biggestSalary` again, we receive a null pointer exception.
@@ -46,14 +46,14 @@ To overcome this problem, we can introduce a `NullJob` class and change the abov
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_simple_example3,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_simple_example3,indent=0]
 ----
 
 This works as we require but it's not always the best way to do this with Groovy. Groovy's safe-dereference operator (`?.`) operator and null aware closures often allow Groovy to avoid the need to create a special null object or null class. This is illustrated by examining a groovier way to write the above example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_simple_example4,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_simple_example4,indent=0]
 ----
 
 Two things are going on here to allow this to work. First of all, `max()` is __'null aware'__ so that ++[300, null, 400].max() == 400++. Secondly, with the `?.` operator, an expression like `p?.job?.salary` will be equal to null if `salary` is equal to null, or if `job` is equal ` null or if `p` is equal to null. You don't need to code a complex nested ++if ... then ... else++ to avoid a `NullPointerException`.
@@ -66,14 +66,14 @@ Our first attempt has special logic within the calculation methods to handle nul
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_tree_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_tree_example,indent=0]
 ----
 
 If we introduce the null object pattern (here by defining the `NullTree` class), we can now simplify the logic in the `size()`, `sum()` and`product()` methods. These methods now much more clearly represent the logic for the normal (and now universal) case. Each of the methods within `NullTree` returns a value which represents doing nothing.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=null_object_tree_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=null_object_tree_example2,indent=0]
 ----
 
 The result of running either of these examples is:
diff --git a/src/spec/doc/fragment_design-pattern-pimp-my-library.adoc b/src/spec/doc/design-pattern-pimp-my-library.adoc
similarity index 92%
rename from src/spec/doc/fragment_design-pattern-pimp-my-library.adoc
rename to src/spec/doc/design-pattern-pimp-my-library.adoc
index 6a0cc1f..3419409 100644
--- a/src/spec/doc/fragment_design-pattern-pimp-my-library.adoc
+++ b/src/spec/doc/design-pattern-pimp-my-library.adoc
@@ -32,7 +32,7 @@ First, we'll define a suitable category.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=pimp_my_library_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=pimp_my_library_example,indent=0]
 ----
 
 We have added two methods which augment the Integer methods by providing the `greaterThanAll` method. Categories follow conventions where they are defined as static methods with a special first parameter representing the class we wish to extend. The ++greaterThanAll(Integer self, others)++ static method becomes the `greaterThanAll(other)` instance method.
@@ -43,7 +43,7 @@ Here is how you would use the category.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=pimp_my_library_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=pimp_my_library_example2,indent=0]
 ----
 
 As you can see, using this technique you can effectively enrich an original class without having access to its source code. Moreover, you can apply different enrichments in different parts of the system as well as work with un-enriched objects if we need to.
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-proxy.adoc b/src/spec/doc/design-pattern-proxy.adoc
similarity index 65%
rename from src/spec/doc/fragment_design-pattern-proxy.adoc
rename to src/spec/doc/design-pattern-proxy.adoc
index b0e6b99..94c2d56 100644
--- a/src/spec/doc/fragment_design-pattern-proxy.adoc
+++ b/src/spec/doc/design-pattern-proxy.adoc
@@ -22,7 +22,7 @@
 = Proxy Pattern
 
 
-The https://en.wikipedia.org/wiki/Proxy_pattern[Proxy Pattern] allows one object to act as a pretend replacement for some other object. In general, whoever is using the proxy, doesn't realise that they are not using the real thing. The pattern is useful when the real object is hard to create or use: it may exist over a network connection, or be a large object in memory, or be a file, database or some other resource that is expensive or impossible to duplicate.
+The http://en.wikipedia.org/wiki/Proxy_pattern[Proxy Pattern] allows one object to act as a pretend replacement for some other object. In general, whoever is using the proxy, doesn't realise that they are not using the real thing. The pattern is useful when the real object is hard to create or use: it may exist over a network connection, or be a large object in memory, or be a file, database or some other resource that is expensive or impossible to duplicate.
 
 == Example
 
@@ -30,12 +30,12 @@ One common use of the proxy pattern is when talking to remote objects in a diffe
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=proxy_client,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=proxy_client,indent=0]
 ----
 
 Here is what your server code might look like (start this first):
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=proxy_server,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=proxy_server,indent=0]
 ----
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-singleton.adoc b/src/spec/doc/design-pattern-singleton.adoc
similarity index 90%
rename from src/spec/doc/fragment_design-pattern-singleton.adoc
rename to src/spec/doc/design-pattern-singleton.adoc
index add6543..a8287d7 100644
--- a/src/spec/doc/fragment_design-pattern-singleton.adoc
+++ b/src/spec/doc/design-pattern-singleton.adoc
@@ -35,7 +35,7 @@ Suppose we wish to create a class for collecting votes. Because getting the righ
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_vote_collector,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_vote_collector,indent=0]
 ----
 
 Some points of interest about this code:
@@ -49,7 +49,7 @@ We can use this singleton class in some script code as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_vote_collector_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_vote_collector_usage,indent=0]
 ----
 
 Here we used the instance 3 times. The second usage was even in a different thread (but don't try this in a scenario with a new class loader).
@@ -77,21 +77,21 @@ First we define some base classes. A `Calculator` class which performs calculati
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_meta_programming_classes,indent=0]
 ----
 
 Now we can define and register a __MetaClass__ which intercepts all attempts to create a `Calculator` object and always provides a pre-created instance instead. We also register this MetaClass with the Groovy system:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_meta_class,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_meta_programming_meta_class,indent=0]
 ----
 
 Now we use instances of our `Client` class from within a script. The client class will attempt to create new instances of the calculator but will always get the singleton.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_meta_programming_usage,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_meta_programming_usage,indent=0]
 ----
 
 Here is the result of running this script (your hashcode values may vary):
@@ -111,7 +111,7 @@ Guice is a Java-oriented framework that supports Interface-Oriented design. Henc
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_guice,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_guice,indent=0]
 ----
 
 Note the `@Inject` annotation in the `Client` class. We can always tell right in the source code which fields will be injected.
@@ -122,7 +122,7 @@ In other scenarios (though probably not in large systems), we could choose to ex
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_guice2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_guice2,indent=0]
 ----
 
 Note the `@Singleton` annotation on the `CalculatorImpl` class and the `@ImplementedBy` annotation in the `Calculator` interface.
@@ -142,7 +142,7 @@ We can do the Calculator example again using Spring as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=singleton_spring,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=singleton_spring,indent=0]
 ----
 
 And here is the result (your hashcode values will vary):
diff --git a/src/spec/doc/fragment_design-pattern-state.adoc b/src/spec/doc/design-pattern-state.adoc
similarity index 66%
rename from src/spec/doc/fragment_design-pattern-state.adoc
rename to src/spec/doc/design-pattern-state.adoc
index 06bb6e4..e99a016 100644
--- a/src/spec/doc/fragment_design-pattern-state.adoc
+++ b/src/spec/doc/design-pattern-state.adoc
@@ -22,7 +22,7 @@
 = State Pattern
 
 
-The https://en.wikipedia.org/wiki/State_pattern[State Pattern] provides a structured approach to partitioning the behaviour within complex systems. The overall behaviour of a system is partitioned into well-defined states. Typically, each state is implemented by a class. The overall system behaviour can be determined firstly by knowing the __current state__ of the system; secondly, by understanding the behaviour possible while in that state (as embodied in the methods of the class corres [...]
+The http://en.wikipedia.org/wiki/State_pattern[State Pattern] provides a structured approach to partitioning the behaviour within complex systems. The overall behaviour of a system is partitioned into well-defined states. Typically, each state is implemented by a class. The overall system behaviour can be determined firstly by knowing the __current state__ of the system; secondly, by understanding the behaviour possible while in that state (as embodied in the methods of the class corresp [...]
 
 == Example
 
@@ -30,7 +30,7 @@ Here is an example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_example,indent=0]
 ----
 
 Here is the output:
@@ -53,14 +53,14 @@ One approach we could take is to leverage http://www.pragmaticprogrammer.com/tit
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation1_interface,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation1_interface,indent=0]
 ----
 
 Then our `Client`, `Online` and 'Offline` classes could be modified to implement that interface, e.g.:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation1_impl,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation1_impl,indent=0]
 ----
 
 You might ask: Haven't we just introduced additional boilerplate code? Can't we rely on duck-typing for this? The answer is 'yes' and 'no'. We can get away with duck-typing but one of the key intentions of the state pattern is to partition complexity. If we know that the __client__ class and each __state__ class all satisfy one interface, then we have placed some key boundaries around the complexity. We can look at any state class in isolation and know the bounds of behaviour possible fo [...]
@@ -73,14 +73,14 @@ Alternatively, or in combination with other variations, we might decide to extra
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation2_classes,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation2_classes,indent=0]
 ----
 
 This is all quite generic and can be used wherever we want to introduce the state pattern. Here is what our code would look like now:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation2_impl,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation2_impl,indent=0]
 ----
 
 You can see here the `startFrom` and `transitionTo` methods begin to give our example code a DSL feel.
@@ -89,27 +89,25 @@ You can see here the `startFrom` and `transitionTo` methods begin to give our ex
 
 Alternatively, or in combination with other variations, we might decide to fully embrace a Domain Specific Language (DSL) approach to this example.
 
-We can define the following generic helper functions (first discussed https://web.archive.org/web/20170624004445/http://www.bytemycode.com:80/snippets/snippet/640/[here]):
+We can define the following generic helper functions (first discussed http://www.bytemycode.com/snippets/snippet/640/[here]):
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation31,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation31,indent=0]
 ----
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation32,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation32,indent=0]
 ----
 
 Now we can define and test our state machine like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=state_variation33,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=state_variation33,indent=0]
 ----
 
-This example isn't an exact equivalent of the others. It doesn't use predefined `Online` and `Offline` classes.
-Instead, it defines the entire state machine on the fly as needed.
-See the https://web.archive.org/web/20170624004445/http://www.bytemycode.com:80/snippets/snippet/640/[previous reference] for more elaborate examples of this style.
+This example isn't an exact equivalent of the others. It doesn't use predefined `Online` and `Offline` classes. Instead it defines the entire state machine on the fly as needed. See the http://www.bytemycode.com/snippets/snippet/640/[previous reference] for more elaborate examples of this style.
 
-See also: https://web.archive.org/web/20150102211229/http://groovy.codehaus.org/Model-based+testing+using+ModelJUnit[Model-based testing using ModelJUnit]
+See also: <<_model_based_testing_using_modeljunit,Model-based testing using ModelJUnit>>
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-strategy.adoc b/src/spec/doc/design-pattern-strategy.adoc
similarity index 91%
rename from src/spec/doc/fragment_design-pattern-strategy.adoc
rename to src/spec/doc/design-pattern-strategy.adoc
index 5d54a7b..e005202 100644
--- a/src/spec/doc/fragment_design-pattern-strategy.adoc
+++ b/src/spec/doc/design-pattern-strategy.adoc
@@ -21,6 +21,7 @@
 
 = Strategy Pattern
 
+
 The http://en.wikipedia.org/wiki/Strategy_pattern[Strategy Pattern] allows you to abstract away particular algorithms from their usage. This allows you to easily swap the algorithm being used without having to change the calling code. The general form of the pattern is:
 
 image::assets/img/StrategyClasses.gif[]
@@ -33,7 +34,7 @@ First let's look at the traditional way of encapsulating the Strategy Pattern.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=strategy_traditional,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=strategy_traditional,indent=0]
 ----
 
 Here we have defined an interface `Calc` which our concrete strategy classes will implement (we could also have used an abstract class). We then defined two algorithms for doing simple multiplication: `CalcByMult` the normal way, and ++CalcByManyAdds++ using only addition (don't try this one using negative numbers - yes we could fix this but it would just make the example longer). We then use normal http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming[polymorphism] to [...]
@@ -42,6 +43,6 @@ Here is the Groovier way to achieve the same thing using Closures:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=strategy_groovy_way,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=strategy_groovy_way,indent=0]
 ----
 
diff --git a/src/spec/doc/fragment_design-pattern-template-method.adoc b/src/spec/doc/design-pattern-template-method.adoc
similarity index 84%
rename from src/spec/doc/fragment_design-pattern-template-method.adoc
rename to src/spec/doc/design-pattern-template-method.adoc
index ccefcf7..4a2740f 100644
--- a/src/spec/doc/fragment_design-pattern-template-method.adoc
+++ b/src/spec/doc/design-pattern-template-method.adoc
@@ -32,7 +32,7 @@ In this example, `Accumulator` captures the essence of the accumulation algorith
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=template_method_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=template_method_example,indent=0]
 ----
 
 The resulting output is:
@@ -46,7 +46,7 @@ In this particular case, you could use Groovy's inject method to achieve a simil
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=template_method_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=template_method_example2,indent=0]
 ----
 
 Thanks to duck-typing, this would also work with other objects which support an add (plus() in Groovy) method, e.g.:
@@ -55,14 +55,14 @@ In this particular case, you could use Groovy's inject method to achieve a simil
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=template_method_example3,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=template_method_example3,indent=0]
 ----
 
 We could also do the multiplication case as follows:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=template_method_example4,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=template_method_example4,indent=0]
 ----
 
 Using closures this way looks more like the <<_strategy_pattern,Strategy Pattern>> but if we realise that the built-in ++inject++ method is the generic part of the algorithm for our template method, then the Closures become the customised parts of the template method pattern.
\ No newline at end of file
diff --git a/src/spec/doc/fragment_design-pattern-visitor.adoc b/src/spec/doc/design-pattern-visitor.adoc
similarity index 91%
rename from src/spec/doc/fragment_design-pattern-visitor.adoc
rename to src/spec/doc/design-pattern-visitor.adoc
index 2923ee8..0a9d788 100644
--- a/src/spec/doc/fragment_design-pattern-visitor.adoc
+++ b/src/spec/doc/design-pattern-visitor.adoc
@@ -32,7 +32,7 @@ This example considers how to calculate the bounds of shapes (or collections of
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_simple_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_simple_example,indent=0]
 ----
 
 That took quite a bit of code.
@@ -41,21 +41,21 @@ We can improve the clarity of our code (and make it about half the size) by maki
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_simple_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_simple_example2,indent=0]
 ----
 
 == Advanced Example
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_advanced_example,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_advanced_example,indent=0]
 ----
 
 If we now use `NodeType1Counter` on a tree like this:
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_advanced_example2,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_advanced_example2,indent=0]
 ----
 
 Then we have one `NodeType1` object as root and one of the children is also a `NodeType1` instance. The other child is a `NodeType2` instance. That means using `NodeType1Counter` here should count 2 `NodeType1` objects.
@@ -74,7 +74,7 @@ Then you have a problem. since the node describes how to iterate, you have no in
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_advanced_example3,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_advanced_example3,indent=0]
 ----
 
 Some small changes but with big effect... the visitor is now recursive and tells me how to iterate. The implementation in the Nodes is minimized to `visitor.visit(this)`, `DefaultVisitor` is now able to catch the new types, we can stop iteration by not delegating to super. Of course the big disadvantage now is that it is no longer iterative, but you can't get all the benefits.
@@ -89,14 +89,14 @@ But don't let us stop here... do we need the `Visitor` interface? If we don't ha
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_advanced_example4,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_advanced_example4,indent=0]
 ----
 
 Looks like we saved a few lines of code here. But we made more. The `Visitable` nodes now do not refer to any `Visitor` class or interface. For me this is the best level of separation you could get here. But do we really need to stop here? No. Let us change the `Visitable` interface a little and let it return the children we want to visit next. This allows us a general iteration method.
 
 [source,groovy]
 ----
-include::{includedir}/../test/DesignPatternsTest.groovy[tags=visitor_advanced_example5,indent=0]
+include::{projectdir}/src/spec/test/DesignPatternsTest.groovy[tags=visitor_advanced_example5,indent=0]
 ----
 
 `DefaultVisitor` now looks a bit different. I added a `doIteration` method that will get the children it should iterate over and then call visit on each element. Per default this will call `visit(Visitable)` which then iterates over the children of this child. I changed `Visitable` to ensure that any node will be able to return children (even if empty). I didn't have to change the `NodeType1` and `NodeType2` class, because the way the children filed was defined already made them a proper [...]
diff --git a/src/spec/doc/guide-integrating.adoc b/src/spec/doc/guide-integrating.adoc
index 3c121dc..094bd18 100644
--- a/src/spec/doc/guide-integrating.adoc
+++ b/src/spec/doc/guide-integrating.adoc
@@ -37,14 +37,14 @@ method:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=eval_me,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=eval_me,indent=0]
 ----
 
 `Eval` supports multiple variants that accept parameters for simple evaluation:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=eval_x,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=eval_x,indent=0]
 ----
 <1> Simple evaluation with one bound parameter named `x`
 <2> Same evaluation, with a custom bound parameter named `k`
@@ -63,7 +63,7 @@ class offers more options.
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_simple,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_simple,indent=0]
 ----
 <1> create a new `GroovyShell` instance
 <2> can be used as `Eval` with direct execution of the code
@@ -77,7 +77,7 @@ It is possible to share data between the application and the script using a `gro
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_binding,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_binding,indent=0]
 ----
 <1> create a new `Binding` that will contain shared data
 <2> create a `GroovyShell` using this shared data
@@ -89,7 +89,7 @@ Note that it is also possible to write from the script into the binding:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_binding_output,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_binding_output,indent=0]
 ----
 <1> create a new `Binding` instance
 <2> create a new `GroovyShell` using that shared data
@@ -101,7 +101,7 @@ It is important to understand that you need to use an undeclared variable if you
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_binding_localvariable,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_binding_localvariable,indent=0]
 ----
 
 WARNING: You must be very careful when using shared data in a multithreaded environment. The `Binding` instance that
@@ -112,7 +112,7 @@ by `parse`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_parse_binding,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_parse_binding,indent=0]
 ----
 <1> will store the `x` variable inside `b1`
 <2> will store the `x` variable inside `b2`
@@ -123,7 +123,7 @@ script instances:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=groovyshell_threadsafe,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=groovyshell_threadsafe,indent=0]
 ----
 <1> create an instance of script for thread 1
 <2> create an instance of script for thread 2
@@ -144,7 +144,7 @@ the example below:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=custom_script_scriptclass,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=custom_script_scriptclass,indent=0]
 ----
 
 The custom class defines a property called `name` and a new method called `greet`. This class can be used as the script
@@ -152,9 +152,9 @@ base class by using a custom configuration:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=custom_script_imports,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=custom_script_imports,indent=0]
 
-include::{includedir}/../test/IntegrationTest.groovy[tags=custom_script_usage,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=custom_script_usage,indent=0]
 ----
 <1> create a `CompilerConfiguration` instance
 <2> instruct it to use `MyScript` as the base class for scripts
@@ -162,7 +162,7 @@ include::{includedir}/../test/IntegrationTest.groovy[tags=custom_script_usage,in
 <4> the script now has access to the new method `greet`
 
 NOTE: You are not limited to the sole _scriptBaseClass_ configuration. You can use any of the compiler configuration
-tweaks, including the <<core-domain-specific-languages.adoc#compilation-customizers,compilation customizers>>.
+tweaks, including the <<compilation-customizers,compilation customizers>>.
 
 [[groovyclassloader]]
 === GroovyClassLoader
@@ -176,7 +176,7 @@ of scripts:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=gcl,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gcl,indent=0]
 ----
 <1> create a new `GroovyClassLoader`
 <2> `parseClass` will return an instance of `Class`
@@ -189,7 +189,7 @@ particular, if you execute the same script twice, if it is a String, then you ob
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=gcl_distinct_classes,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gcl_distinct_classes,indent=0]
 ----
 <1> dynamically create a class named "Foo"
 <2> create an identical looking class, using a separate `parseClass` call
@@ -201,7 +201,7 @@ then the source *must* be a file, like in this example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=gcl_same_classes,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gcl_same_classes,indent=0]
 ----
 <1> parse a class from a `File`
 <2> parse a class from a distinct file instance, but pointing to the same physical file
@@ -224,18 +224,18 @@ a directory with the following script inside:
 [source,groovy]
 .ReloadingTest.groovy
 ----
-include::{includedir}/../test-resources/reloading/source1.groovy[tags=greeter,indent=0]
+include::{projectdir}/src/spec/test-resources/reloading/source1.groovy[tags=greeter,indent=0]
 ----
 
 then you can execute this code using a `GroovyScriptEngine`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/IntegrationTest.groovy[tags=gse_init,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gse_init,indent=0]
 
-include::{includedir}/../test/IntegrationTest.groovy[tags=gse_script_fakeloop_begin,indent=0]
-include::{includedir}/../test/IntegrationTest.groovy[tags=gse_script1,indent=4]
-include::{includedir}/../test/IntegrationTest.groovy[tags=gse_script_fakeloop_end,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gse_script_fakeloop_begin,indent=0]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gse_script1,indent=4]
+include::{projectdir}/src/spec/test/IntegrationTest.groovy[tags=gse_script_fakeloop_end,indent=0]
 ----
 <1> create a script engine which will look for sources into our source directory
 <2> execute the script, which will return an instance of `Greeter`
@@ -254,7 +254,7 @@ Hello, world!
 [source,groovy]
 .ReloadingTest.groovy
 ----
-include::{includedir}/../test-resources/reloading/source2.groovy[tags=greeter,indent=0]
+include::{projectdir}/src/spec/test-resources/reloading/source2.groovy[tags=greeter,indent=0]
 ----
 
 And the message should change to:
@@ -273,7 +273,7 @@ the same directory, without interrupting the executing script:
 [source,groovy]
 .Depencency.groovy
 ----
-include::{includedir}/../test-resources/reloading/dependency1.groovy[tags=dependency,indent=0]
+include::{projectdir}/src/spec/test-resources/reloading/dependency1.groovy[tags=dependency,indent=0]
 ----
 
 and update the `ReloadingTest` script like this:
@@ -281,7 +281,7 @@ and update the `ReloadingTest` script like this:
 [source,groovy]
 .ReloadingTest.groovy
 ----
-include::{includedir}/../test-resources/reloading/source3.groovy[tags=greeter,indent=0]
+include::{projectdir}/src/spec/test-resources/reloading/source3.groovy[tags=greeter,indent=0]
 ----
 
 And this time, the message should change to:
@@ -299,7 +299,7 @@ And as a last test, you can update the `Dependency.groovy` file without touching
 [source,groovy]
 .Depencency.groovy
 ----
-include::{includedir}/../test-resources/reloading/dependency2.groovy[tags=dependency,indent=0]
+include::{projectdir}/src/spec/test-resources/reloading/dependency2.groovy[tags=dependency,indent=0]
 ----
 
 And you should observe that the dependent file was reloaded:
@@ -320,8 +320,8 @@ stub generation is done, for the joint compiler.
 
 However, overriding `CompilationUnit` is not recommended and should only be done if no other standard solution works.
 
-include::{rootprojectdir}/subprojects/groovy-bsf/{specfolder}/fragment_integrating-bsf.adoc[leveloffset=+1]
+include::{projectdir}/subprojects/groovy-bsf/{specfolder}/integrating-bsf.adoc[leveloffset=+1]
 
-include::{rootprojectdir}/subprojects/groovy-jsr223/{specfolder}/fragment_integrating-jsr223.adoc[leveloffset=+1]
+include::{projectdir}/subprojects/groovy-jsr223/{specfolder}/integrating-jsr223.adoc[leveloffset=+1]
 
 
diff --git a/src/spec/doc/index.adoc b/src/spec/doc/index.adoc
index 5859eab..455b786 100644
--- a/src/spec/doc/index.adoc
+++ b/src/spec/doc/index.adoc
@@ -21,74 +21,73 @@
 
 = Groovy Language Documentation
 :doctype: book
+ifndef::projectdir[:projectdir: ../../..]
 
-include::{includedir}/core-introduction.adoc[]
+include::{projectdir}/src/spec/doc/core-introduction.adoc[]
 
 == Groovy Language Specification
 
-include::{includedir}/core-syntax.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-syntax.adoc[leveloffset=+2]
 
-include::{includedir}/core-operators.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-operators.adoc[leveloffset=+2]
 
-include::{includedir}/core-program-structure.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-program-structure.adoc[leveloffset=+2]
 
-include::{includedir}/core-object-orientation.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-object-orientation.adoc[leveloffset=+2]
 
-include::{includedir}/core-closures.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-closures.adoc[leveloffset=+2]
 
-include::{includedir}/core-semantics.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-semantics.adoc[leveloffset=+2]
 
 == Tools
 
-include::{includedir}/tools-groovy.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/tools-groovy.adoc[leveloffset=+2]
 
-include::{includedir}/tools-groovyc.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/tools-groovyc.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-groovysh/{specfolder}/groovysh.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-groovysh/{specfolder}/groovysh.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-console/{specfolder}/groovy-console.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-console/{specfolder}/groovy-console.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-groovydoc/{specfolder}/groovydoc.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-groovydoc/{specfolder}/groovydoc.adoc[leveloffset=+2]
 
-include::{includedir}/tools-ide.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/tools-ide.adoc[leveloffset=+2]
 
 == User Guides
 
-include::{includedir}/core-getting-started.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-getting-started.adoc[leveloffset=+2]
 
-include::{includedir}/core-differences-java.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-differences-java.adoc[leveloffset=+2]
 
-include::{includedir}/core-gdk.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-gdk.adoc[leveloffset=+2]
 
-include::{includedir}/core-metaprogramming.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-metaprogramming.adoc[leveloffset=+2]
 
-include::{includedir}/grape.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/grape.adoc[leveloffset=+2]
 
-include::{includedir}/core-testing-guide.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-testing-guide.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-json/{specfolder}/json-userguide.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-json/{specfolder}/json-userguide.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-sql/{specfolder}/sql-userguide.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-sql/{specfolder}/sql-userguide.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-xml/{specfolder}/xml-userguide.adoc[leveloffset=+2]
-
-include::{rootprojectdir}/subprojects/groovy-yaml/{specfolder}/yaml-userguide.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-xml/{specfolder}/xml-userguide.adoc[leveloffset=+2]
 
 === Scripting Ant tasks
 
-Groovy integrates very well with http://ant.apache.org[Apache Ant] thanks to <<antbuilder,AntBuilder>>.
+Groovy integrates very well with http://ant.apache.org[Apache Ant] thanks to <<_antbuilder,AntBuilder>>.
 
-include::{rootprojectdir}/subprojects/groovy-ant/{specfolder}/groovy-ant-task.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-ant/{specfolder}/groovy-ant-task.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-templates/{specfolder}/template-engines.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-templates/{specfolder}/template-engines.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-servlet/{specfolder}/servlet-userguide.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-servlet/{specfolder}/servlet-userguide.adoc[leveloffset=+2]
 
-include::{includedir}/guide-integrating.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/guide-integrating.adoc[leveloffset=+2]
 
-include::{includedir}/core-domain-specific-languages.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/core-domain-specific-languages.adoc[leveloffset=+2]
 
-include::{rootprojectdir}/subprojects/groovy-jmx/{specfolder}/jmx.adoc[leveloffset=+2]
+include::{projectdir}/subprojects/groovy-jmx/src/spec/doc/jmx.adoc[leveloffset=+2]
 
 === Creating Swing UIs
 
@@ -99,11 +98,11 @@ Creating Swing UIs is made easy thanks to the use of <<swingbuilder,SwingBuilder
 (TBD)
 
 
-include::{includedir}/design-patterns-in-groovy.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/design-pattern-in-groovy.adoc[leveloffset=+2]
 
 == Acknowledgements
 
-include::{includedir}/contributors.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/contributors.adoc[leveloffset=+2]
 
-include::{includedir}/license.adoc[leveloffset=+2]
+include::{projectdir}/src/spec/doc/license.adoc[leveloffset=+2]
 
diff --git a/src/spec/doc/style-guide.adoc b/src/spec/doc/style-guide.adoc
index d83ef19..fdb47e1 100644
--- a/src/spec/doc/style-guide.adoc
+++ b/src/spec/doc/style-guide.adoc
@@ -486,7 +486,7 @@ Here are some examples of those native constructs:
 
 [source,groovy]
 ----
-include::{includedir}/../test/StyleGuideTest.groovy[tags=data_structures,indent=0]
+include::{projectdir}/src/spec/test/StyleGuideTest.groovy[tags=data_structures,indent=0]
 ----
 
 == The Groovy Development Kit
diff --git a/src/spec/doc/fragment_type-checking-extensions.adoc b/src/spec/doc/type-checking-extensions.adoc
similarity index 91%
rename from src/spec/doc/fragment_type-checking-extensions.adoc
rename to src/spec/doc/type-checking-extensions.adoc
index ababeec..8c281f2 100644
--- a/src/spec/doc/fragment_type-checking-extensions.adoc
+++ b/src/spec/doc/type-checking-extensions.adoc
@@ -35,7 +35,7 @@ example, you wouldn’t be able to use type checking on code that uses the marku
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=intro_stc_extensions,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=intro_stc_extensions,indent=0]
 ----
 
 In the previous example, none of the `html`, `head`, `body` or `p` methods
@@ -131,14 +131,14 @@ Imagine that you have this rover DSL at hand. A user would write:
 
 [source,groovy]
 --------------
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
 --------------
 
 If you have a class defined as such:
 
 [source,groovy]
 ----------------------------
-include::{includedir}/../test/typing/Robot.groovy[tags=example_robot_classdef,indent=0]
+include::{projectdir}/src/spec/test/typing/Robot.groovy[tags=example_robot_classdef,indent=0]
 ----------------------------
 
 The script can be type checked before being executed using the following
@@ -146,7 +146,7 @@ script:
 
 [source,groovy]
 ------------------------------------------------------------------------------
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup,indent=0]
 ------------------------------------------------------------------------------
 <1> a compiler configuration adds the `@TypeChecked` annotation to all classes
 <2> use the configuration in a `GroovyShell`
@@ -157,7 +157,7 @@ transparently to the script. In that case, it will fail at compile
 time:
 
 ------------------------------------------------------------
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_expected_err,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_expected_err,indent=0]
 ------------------------------------------------------------
 
 Now, we will slightly update the configuration to include the
@@ -165,7 +165,7 @@ Now, we will slightly update the configuration to include the
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_fixed_conf,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_fixed_conf,indent=0]
 ----
 
 Then add the following to your classpath:
@@ -173,7 +173,7 @@ Then add the following to your classpath:
 [source,groovy]
 .robotextension.groovy
 -------------------------------------
-include::{includedir}/../test-resources/robotextension.groovy[tags=example_robot_extension,indent=0]
+include::{projectdir}/src/spec/test-resources/robotextension.groovy[tags=example_robot_extension,indent=0]
 -------------------------------------
 
 Here, we’re telling the compiler that if an _unresolved variable_ is found
@@ -211,7 +211,7 @@ script can react:
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/setup.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/setup.groovy[tags=event,indent=0]
 ----
 
 Can be used to perform setup of your extension
@@ -231,7 +231,7 @@ Can be used to perform setup of your extension
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/finish.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/finish.groovy[tags=event,indent=0]
 ----
 
 Can be used to perform additional checks after the type checker has finished its job.
@@ -251,7 +251,7 @@ Can be used to perform additional checks after the type checker has finished its
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/unresolvedvariable.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/unresolvedvariable.groovy[tags=event,indent=0]
 ----
 
 Allows the developer to help the type checker with user-injected variables.
@@ -271,7 +271,7 @@ Allows the developer to help the type checker with user-injected variables.
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/unresolvedproperty.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/unresolvedproperty.groovy[tags=event,indent=0]
 ----
 
 Allows the developer to handle "dynamic" properties
@@ -291,7 +291,7 @@ Allows the developer to handle "dynamic" properties
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/unresolvedattribute.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/unresolvedattribute.groovy[tags=event,indent=0]
 ----
 
 Allows the developer to handle missing attributes
@@ -311,7 +311,7 @@ Allows the developer to handle missing attributes
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/beforemethodcall.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/beforemethodcall.groovy[tags=event,indent=0]
 ----
 
 Allows you to intercept method calls before the
@@ -335,7 +335,7 @@ checker skips its own checks.
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/aftermethodcall.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/aftermethodcall.groovy[tags=event,indent=0]
 ----
 
 Allow you to perform additional checks after the type
@@ -360,7 +360,7 @@ other.Note that `afterMethodCall` is called even if you did
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/onmethodselection.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/onmethodselection.groovy[tags=event,indent=0]
 ----
 
 The type checker works by inferring
@@ -386,7 +386,7 @@ of expressions, not only method calls (binary expressions for example).
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/methodnotfound.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/methodnotfound.groovy[tags=event,indent=0]
 ----
 
 Unlike `onMethodSelection`, this event is
@@ -418,7 +418,7 @@ directly instead of wrapping it into a list.
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/beforevisitmethod.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/beforevisitmethod.groovy[tags=event,indent=0]
 ----
 
 The type checker will call this method before
@@ -443,7 +443,7 @@ only if you are inside method foo).
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/aftervisitmethod.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/aftervisitmethod.groovy[tags=event,indent=0]
 ----
 
 Gives you the opportunity to perform additional
@@ -465,7 +465,7 @@ additional checks once everything has been collected.
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/beforevisitclass.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/beforevisitclass.groovy[tags=event,indent=0]
 ----
 
 If a class is type checked, then
@@ -490,7 +490,7 @@ implementation. For that, you would have to set the `handled` flag to
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/aftervisitclass.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/aftervisitclass.groovy[tags=event,indent=0]
 ----
 
 Called
@@ -514,7 +514,7 @@ inner/anonymous class defined in the same class with is not skipped.
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/incompatibleassignment.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/incompatibleassignment.groovy[tags=event,indent=0]
 ----
 
 Gives the
@@ -539,7 +539,7 @@ valid (using `handled` set to `true`).
 |
 [source,groovy]
 ----
-include::{includedir}/../test-resources/ambiguousmethods.groovy[tags=event,indent=0]
+include::{projectdir}/src/spec/test-resources/ambiguousmethods.groovy[tags=event,indent=0]
 ----
 
 Gives the
@@ -605,7 +605,7 @@ write:
 
 [source,groovy]
 --------------------
-include::{includedir}/../test-resources/selfcheck.groovy[tags=classnodefor,indent=0]
+include::{projectdir}/src/spec/test-resources/selfcheck.groovy[tags=classnodefor,indent=0]
 --------------------
 
 You would also note that there is a variant of _classNodeFor_ that takes
@@ -625,7 +625,7 @@ using `lookupClassNodeFor`:
 
 [source,groovy]
 ----
-include::{includedir}/../test-resources/selfcheck.groovy[tags=lookupclassnodefor,indent=0]
+include::{projectdir}/src/spec/test-resources/selfcheck.groovy[tags=lookupclassnodefor,indent=0]
 ----
 
 [[Typecheckingextensions-Helpingthetypechecker]]
@@ -724,7 +724,7 @@ pretty complex type checking including handling of forward references.
 
 [source,groovy]
 ----------------------------------------------------------------------------------------------
-include::{includedir}/../test-resources/newmethod.groovy[tags=newmethod,indent=0]
+include::{projectdir}/src/spec/test-resources/newmethod.groovy[tags=newmethod,indent=0]
 ----------------------------------------------------------------------------------------------
 
 Should you need more than the name and return type, you can always
@@ -781,8 +781,8 @@ you would handle forward references: 
 
 [source,groovy]
 ------------------------------------------------------
-include::{includedir}/../test-resources/scoping.groovy[tags=newscope,indent=0]
-include::{includedir}/../test-resources/scoping.groovy[tags=scopeexit,indent=0]
+include::{projectdir}/src/spec/test-resources/scoping.groovy[tags=newscope,indent=0]
+include::{projectdir}/src/spec/test-resources/scoping.groovy[tags=scopeexit,indent=0]
 ------------------------------------------------------
 
 That is to say, that if at some point you are not able to determine the
@@ -793,7 +793,7 @@ provide some interesting syntactic sugar:
 
 [source,groovy]
 ------------------------------------------------------
-include::{includedir}/../test-resources/scoping_alt.groovy[tags=newscope,indent=0]
+include::{projectdir}/src/spec/test-resources/scoping_alt.groovy[tags=newscope,indent=0]
 ------------------------------------------------------
 
 At anytime in the DSL, you can access the current scope
@@ -801,7 +801,7 @@ using `getCurrentScope()` or more simply `currentScope`:
 
 [source,groovy]
 ------------------------------------------------------
-include::{includedir}/../test-resources/scoping_alt.groovy[tags=currentscope,indent=0]
+include::{projectdir}/src/spec/test-resources/scoping_alt.groovy[tags=currentscope,indent=0]
 ------------------------------------------------------
 
 The general schema would then be:
@@ -857,7 +857,7 @@ script becomes the body of the main method of a type checking extension class, a
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/PrecompiledExtension.groovy[tags=precompiled_groovy_extension,indent=0]
+include::{projectdir}/src/spec/test/typing/PrecompiledExtension.groovy[tags=precompiled_groovy_extension,indent=0]
 ----
 <1> extending the `TypeCheckingDSL` class is the easiest
 <2> then the extension code needs to go inside the `run` method
@@ -867,7 +867,7 @@ Setting up the extension is very similar to using a source form extension:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=setup_precompiled,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=setup_precompiled,indent=0]
 ----
 
 The difference is that instead of using a path in classpath, you just specify the fully qualified class name of the
@@ -878,7 +878,7 @@ The extension above can be rewritten in Java this way:
 
 [source,java]
 ----
-include::{includedir}/../test/typing/PrecompiledJavaExtension.java[tags=precompiled_java_extension,indent=0]
+include::{projectdir}/src/spec/test/typing/PrecompiledJavaExtension.java[tags=precompiled_java_extension,indent=0]
 ----
 <1> extend the `AbstractTypeCheckingExtension` class
 <2> then override the `handleXXX` methods as required
@@ -944,14 +944,14 @@ To illustrate this, let's come back to the `Robot` example:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script,indent=0]
 ----
 
 And let's try to activate our type checking extension using `@CompileStatic` instead of `@TypeChecked`:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic,indent=0]
 ----
 <1> Apply `@CompileStatic` transparently
 <2> Activate the type checking extension
@@ -964,7 +964,7 @@ let's slightly update our example, starting from the robot script:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script_direct,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_script_direct,indent=0]
 ----
 
 Here you can notice that there is no reference to `robot` anymore. Our extension will not help then because we will not
@@ -973,7 +973,7 @@ totally dynamic way thanks to the help of a gapi:groovy.util.DelegatingScript[]:
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_dynamic,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_dynamic,indent=0]
 ----
 <1> we configure the compiler to use a `DelegatingScript` as the base class
 <2> the script source needs to be parsed and will return an instance of `DelegatingScript`
@@ -984,7 +984,7 @@ If we want this to pass with `@CompileStatic`, we have to use a type checking ex
 
 [source,groovy]
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic2,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=example_robot_setup_compilestatic2,indent=0]
 ----
 <1> apply `@CompileStatic` transparently
 <2> use an alternate type checking extension meant to recognize the call to `move`
@@ -995,7 +995,7 @@ extension:
 [source,groovy]
 .robotextension2.groovy
 -------------------------------------
-include::{includedir}/../test-resources/robotextension2.groovy[tags=example_robot_extension,indent=0]
+include::{projectdir}/src/spec/test-resources/robotextension2.groovy[tags=example_robot_extension,indent=0]
 -------------------------------------
 <1> if the call is a method call (not a static method call)
 <2> that this call is made on "implicit this" (no explicit `this.`)
@@ -1008,7 +1008,7 @@ include::{includedir}/../test-resources/robotextension2.groovy[tags=example_robo
 If you try to execute this code, then you could be surprised that it actually fails at runtime:
 
 ----
-include::{includedir}/../test/typing/TypeCheckingExtensionSpecTest.groovy[tags=robot_runtime_error_cs,indent=0]
+include::{projectdir}/src/spec/test/typing/TypeCheckingExtensionSpecTest.groovy[tags=robot_runtime_error_cs,indent=0]
 ----
 
 The reason is very simple: while the type checking extension is sufficient for `@TypeChecked`, which does not involve
@@ -1021,7 +1021,7 @@ Fixing this is very easy and just implies replacing the `newMethod` call with so
 [source,groovy]
 .robotextension3.groovy
 -------------------------------------
-include::{includedir}/../test-resources/robotextension3.groovy[tags=example_robot_extension,indent=0]
+include::{projectdir}/src/spec/test-resources/robotextension3.groovy[tags=example_robot_extension,indent=0]
 -------------------------------------
 <1> tell the compiler that the call should be make dynamic
 
diff --git a/src/spec/doc/windows-nsis-installer.adoc b/src/spec/doc/windows-nsis-installer.adoc
index e0861fb..15bf334 100644
--- a/src/spec/doc/windows-nsis-installer.adoc
+++ b/src/spec/doc/windows-nsis-installer.adoc
@@ -24,7 +24,7 @@
 
 == A Windows-specific installation script
 
-That allows to create installer. You can examine the results on the https://groovy.apache.org/download.html[download page].
+That allows to create installer. You can examine the results on the <<download,download page>>.
 
 image::assets/img/setup.png[]
 
diff --git a/src/spec/doc/fragment_working-with-collections.adoc b/src/spec/doc/working-with-collections.adoc
similarity index 77%
rename from src/spec/doc/fragment_working-with-collections.adoc
rename to src/spec/doc/working-with-collections.adoc
index ed04a0e..0153983 100644
--- a/src/spec/doc/fragment_working-with-collections.adoc
+++ b/src/spec/doc/working-with-collections.adoc
@@ -38,7 +38,7 @@ expression.
 
 [source,groovy]
 -------------------------------------
-include::{includedir}/../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_literals,indent=0]
+include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_literals,indent=0]
 -------------------------------------
 
 Each list expression creates an implementation of {java-util-list}.
@@ -47,7 +47,7 @@ Of course lists can be used as a source to construct another list:
 
 [source,groovy]
 ----------------------------------------------------------------------------
-include::{includedir}/../test/gdk/WorkingWithCollectionsTest.groovy[tags=list_construct,indent=0]
+include::{projectdir}/src/spec/test/gdk/WorkingWithCollectionsTest.groovy[tags=list_construct,indent=0]
 ----------------------------------------------------------------------------
... 1158 lines suppressed ...