diff --git a/Build/bamboo/src/main/java/core/AbstractCoreSpec.java b/Build/bamboo/src/main/java/core/AbstractCoreSpec.java
index b59dae604dae80e17b7f4005b3c27a4e9f8b6277..db62e95d7e093f531df1ec8166199ac151c63062 100644
--- a/Build/bamboo/src/main/java/core/AbstractCoreSpec.java
+++ b/Build/bamboo/src/main/java/core/AbstractCoreSpec.java
@@ -187,19 +187,101 @@ abstract public class AbstractCoreSpec {
         .cleanWorkingDirectory(true);
     }
 
+
+    /**
+     * Job checking CGL of last git commit
+     *
+     * @param String requirementIdentifier
+     */
+    protected Job getJobCglCheckGitCommit(String requirementIdentifier) {
+        return new Job("Integration CGL", new BambooKey("CGLCHECK"))
+            .description("Check coding guidelines by executing Build/Scripts/cglFixMyCommit.sh script")
+            .pluginConfigurations(this.getDefaultJobPluginConfiguration())
+            .tasks(
+                this.getTaskGitCloneRepository(),
+                this.getTaskGitCherryPick(),
+                this.getTaskComposerInstall(requirementIdentifier),
+                new ScriptTask()
+                    .description("Execute cgl check script")
+                    .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
+                    .inlineBody(
+                        this.getScriptTaskBashInlineBody() +
+                        "function cglFixMyCommit() {\n" +
+                        "    docker run \\\n" +
+                        "        -u ${HOST_UID} \\\n" +
+                        "        -v /bamboo-data/${BAMBOO_COMPOSE_PROJECT_NAME}/passwd:/etc/passwd \\\n" +
+                        "        -v ${BAMBOO_COMPOSE_PROJECT_NAME}_bamboo-data:/srv/bamboo/xml-data/build-dir/ \\\n" +
+                        "        --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" +
+                        "        --rm \\\n" +
+                        "        typo3gmbh/" + requirementIdentifier.toLowerCase() + ":latest \\\n" +
+                        "        bin/bash -c \"cd ${PWD}; ./Build/Scripts/cglFixMyCommit.sh $*\"\n" +
+                        "}\n" +
+                        "\n" +
+                        "cglFixMyCommit dryrun\n"
+                    )
+            )
+            .requirements(
+                this.getRequirementDocker10()
+            )
+            .cleanWorkingDirectory(true);
+    }
+
+    /**
+     * Job checking CGL of all core php files
+     *
+     * @param int stageNumber
+     * @param String requirementIdentifier
+     * @param Task composerTask
+     */
+    protected Job getJobCglCheckFullCore(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Integration CGL " + stageNumber, new BambooKey("CGLCHECK" + stageNumber))
+            .description("Check coding guidelines of full core")
+            .pluginConfigurations(this.getDefaultJobPluginConfiguration())
+            .tasks(
+                this.getTaskGitCloneRepository(),
+                this.getTaskGitCherryPick(),
+                composerTask,
+                new ScriptTask()
+                    .description("Execute cgl check")
+                    .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
+                    .inlineBody(
+                        this.getScriptTaskBashInlineBody() +
+                        "function phpCsFixer() {\n" +
+                        "    docker run \\\n" +
+                        "        -u ${HOST_UID} \\\n" +
+                        "        -v /bamboo-data/${BAMBOO_COMPOSE_PROJECT_NAME}/passwd:/etc/passwd \\\n" +
+                        "        -v ${BAMBOO_COMPOSE_PROJECT_NAME}_bamboo-data:/srv/bamboo/xml-data/build-dir/ \\\n" +
+                        "        --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" +
+                        "        --rm \\\n" +
+                        "        typo3gmbh/" + requirementIdentifier.toLowerCase() + ":latest \\\n" +
+                        "        bin/bash -c \"cd ${PWD}; php -n -c /etc/php/cli-no-xdebug/php.ini bin/php-cs-fixer $*\"\n" +
+                        "}\n" +
+                        "\n" +
+                        "phpCsFixer fix -v --dry-run --path-mode intersection --config=Build/.php_cs typo3/\n" +
+                        "exit $?"
+                    )
+            )
+            .requirements(
+                this.getRequirementDocker10()
+            )
+            .cleanWorkingDirectory(true);
+    }
+
     /**
      * Job acceptance test installs system on mariadb
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobAcceptanceTestInstallMysql(String requirementIdentifier) {
-        return new Job("Accept inst my " + requirementIdentifier, new BambooKey("ACINSTMY" + requirementIdentifier))
+    protected Job getJobAcceptanceTestInstallMysql(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Accept inst my " + stageNumber + " " + requirementIdentifier, new BambooKey("ACINSTMY" +stageNumber + requirementIdentifier))
             .description("Install TYPO3 on mariadb and load introduction package " + requirementIdentifier)
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 this.getTaskPrepareAcceptanceTest(),
                 this.getTaskDockerDependenciesAcceptanceInstallMariadb10(),
                 new ScriptTask()
@@ -245,16 +327,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job acceptance test installs system and introduction package on pgsql
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobAcceptanceTestInstallPgsql(String requirementIdentifier) {
-        return new Job("Accept inst pg " + requirementIdentifier, new BambooKey("ACINSTPG" + requirementIdentifier))
+    protected Job getJobAcceptanceTestInstallPgsql(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Accept inst pg " + stageNumber + " " + requirementIdentifier, new BambooKey("ACINSTPG" + stageNumber + requirementIdentifier))
         .description("Install TYPO3 on pgsql and load introduction package " + requirementIdentifier)
         .pluginConfigurations(this.getDefaultJobPluginConfiguration())
         .tasks(
             this.getTaskGitCloneRepository(),
             this.getTaskGitCherryPick(),
-            this.getTaskComposerInstall(requirementIdentifier),
+            composerTask,
             this.getTaskPrepareAcceptanceTest(),
             this.getTaskDockerDependenciesAcceptanceInstallPostgres10(),
             new ScriptTask()
@@ -300,16 +384,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job acceptance test installs system and introduction package on sqlite
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobAcceptanceTestInstallSqlite(String requirementIdentifier) {
-        return new Job("Accept inst sq " + requirementIdentifier, new BambooKey("ACINSTSQ" + requirementIdentifier))
+    protected Job getJobAcceptanceTestInstallSqlite(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Accept inst sq " + stageNumber + " " + requirementIdentifier, new BambooKey("ACINSTSQ" + stageNumber + requirementIdentifier))
         .description("Install TYPO3 on sqlite and load introduction package " + requirementIdentifier)
         .pluginConfigurations(this.getDefaultJobPluginConfiguration())
         .tasks(
             this.getTaskGitCloneRepository(),
             this.getTaskGitCherryPick(),
-            this.getTaskComposerInstall(requirementIdentifier),
+            composerTask,
             this.getTaskPrepareAcceptanceTest(),
             this.getTaskDockerDependenciesAcceptanceInstallSqlite(),
             new ScriptTask()
@@ -351,10 +437,12 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for mysql based acceptance tests
      *
+     * @param int stageNumber
      * @param int numberOfChunks
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobsAcceptanceTestsBackendMysql(int numberOfChunks, String requirementIdentifier) {
+    protected ArrayList<Job> getJobsAcceptanceTestsBackendMysql(int stageNumber, int numberOfChunks, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfChunks; i++) {
@@ -362,13 +450,13 @@ abstract public class AbstractCoreSpec {
             if (i < 10) {
                 formattedI = "0" + i;
             }
-            jobs.add(new Job("Accept my " + requirementIdentifier + " " + formattedI, new BambooKey("ACMY" + requirementIdentifier + formattedI))
+            jobs.add(new Job("Accept my " + stageNumber + " " + requirementIdentifier + " " + formattedI, new BambooKey("ACMY" + stageNumber + requirementIdentifier + formattedI))
                 .description("Run acceptance tests" + requirementIdentifier)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     this.getTaskPrepareAcceptanceTest(),
                     this.getTaskDockerDependenciesAcceptanceBackendMariadb10(),
                     new ScriptTask()
@@ -436,10 +524,12 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for mysql based functional tests
      *
+     * @param int stageNumber
      * @param int numberOfChunks
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobsFunctionalTestsMysql(int numberOfChunks, String requirementIdentifier) {
+    protected ArrayList<Job> getJobsFunctionalTestsMysql(int stageNumber, int numberOfChunks, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfChunks; i++) {
@@ -447,13 +537,13 @@ abstract public class AbstractCoreSpec {
             if (i < 10) {
                 formattedI = "0" + i;
             }
-            jobs.add(new Job("Func mysql " + requirementIdentifier + " " + formattedI, new BambooKey("FMY" + requirementIdentifier + formattedI))
+            jobs.add(new Job("Func mysql " + stageNumber + " " + requirementIdentifier + " " + formattedI, new BambooKey("FMY" + stageNumber + requirementIdentifier + formattedI))
                 .description("Run functional tests on mysql DB " + requirementIdentifier)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     this.getTaskDockerDependenciesFunctionalMariadb10(),
                     this.getTaskSplitFunctionalJobs(numberOfChunks, requirementIdentifier),
                     new ScriptTask()
@@ -500,10 +590,12 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for mssql based functional tests
      *
+     * @param int stageNumber
      * @param int numberOfChunks
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobsFunctionalTestsMssql(int numberOfChunks, String requirementIdentifier) {
+    protected ArrayList<Job> getJobsFunctionalTestsMssql(int stageNumber, int numberOfChunks, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfChunks; i++) {
@@ -511,13 +603,13 @@ abstract public class AbstractCoreSpec {
             if (i < 10) {
                 formattedI = "0" + i;
             }
-            jobs.add(new Job("Func mssql " + requirementIdentifier + " " + formattedI, new BambooKey("FMS" + requirementIdentifier + formattedI))
+            jobs.add(new Job("Func mssql " + stageNumber + " " + requirementIdentifier + " " + formattedI, new BambooKey("FMS" + stageNumber + requirementIdentifier + formattedI))
                 .description("Run functional tests on mysql DB " + requirementIdentifier)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     this.getTaskDockerDependenciesFunctionalMssql(),
                     this.getTaskSplitFunctionalJobs(numberOfChunks, requirementIdentifier),
                     new ScriptTask()
@@ -568,10 +660,12 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for pgsql based functional tests
      *
+     * @param int stageNumber
      * @param int numberOfChunks
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobsFunctionalTestsPgsql(int numberOfChunks, String requirementIdentifier) {
+    protected ArrayList<Job> getJobsFunctionalTestsPgsql(int stageNumber, int numberOfChunks, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfChunks; i++) {
@@ -579,13 +673,13 @@ abstract public class AbstractCoreSpec {
             if (i < 10) {
                 formattedI = "0" + i;
             }
-            jobs.add(new Job("Func pgsql " + requirementIdentifier + " " + formattedI, new BambooKey("FPG" + requirementIdentifier + formattedI))
+            jobs.add(new Job("Func pgsql " + stageNumber + " " + requirementIdentifier + " " + formattedI, new BambooKey("FPG" + stageNumber + requirementIdentifier + formattedI))
                 .description("Run functional tests on pgsql DB " + requirementIdentifier)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     this.getTaskDockerDependenciesFunctionalPostgres10(),
                     this.getTaskSplitFunctionalJobs(numberOfChunks, requirementIdentifier),
                     new ScriptTask()
@@ -633,10 +727,12 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for sqlite based functional tests
      *
+     * @param int stageNumber
      * @param int numberOfChunks
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobsFunctionalTestsSqlite(int numberOfChunks, String requirementIdentifier) {
+    protected ArrayList<Job> getJobsFunctionalTestsSqlite(int stageNumber, int numberOfChunks, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfChunks; i++) {
@@ -644,13 +740,13 @@ abstract public class AbstractCoreSpec {
             if (i < 10) {
                 formattedI = "0" + i;
             }
-            jobs.add(new Job("Func sqlite " + requirementIdentifier + " " + formattedI, new BambooKey("FSL" + requirementIdentifier + formattedI))
+            jobs.add(new Job("Func sqlite " + stageNumber + " " + requirementIdentifier + " " + formattedI, new BambooKey("FSL" + stageNumber + requirementIdentifier + formattedI))
                 .description("Run functional tests on sqlite DB " + requirementIdentifier)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     this.getTaskSplitFunctionalJobs(numberOfChunks, requirementIdentifier),
                     this.getTaskDockerDependenciesFunctionalSqlite(),
                     new ScriptTask()
@@ -694,16 +790,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job with integration test checking for valid @xy annotations
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobIntegrationAnnotations(String requirementIdentifier) {
-        return new Job("Integration annotations", new BambooKey("IANNO"))
+    protected Job getJobIntegrationAnnotations(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Integration annotations " + stageNumber, new BambooKey("IANNO" + stageNumber))
             .description("Check docblock-annotations by executing Build/Scripts/annotationChecker.php script")
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 new ScriptTask()
                     .description("Execute annotations check script")
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -732,17 +830,19 @@ abstract public class AbstractCoreSpec {
     /**
      * Job with various smaller script tests
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobIntegrationVarious(String requirementIdentifier) {
+    protected Job getJobIntegrationVarious(int stageNumber, String requirementIdentifier, Task composerTask) {
         // Exception code checker, xlf, permissions, rst file check
-        return new Job("Integration various", new BambooKey("CDECC"))
+        return new Job("Integration various " + stageNumber, new BambooKey("CDECC" + stageNumber))
             .description("Checks duplicate exceptions, git submodules, xlf files, permissions, rst")
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 new ScriptTask()
                     .description("Run duplicate exception code check script")
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -863,16 +963,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job for javascript unit tests
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobUnitJavaScript(String requirementIdentifier) {
-        return new Job("Unit JavaScript", new BambooKey("JSUT"))
+    protected Job getJobUnitJavaScript(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Unit JavaScript " + stageNumber, new BambooKey("JSUT" + stageNumber))
             .description("Run JavaScript unit tests")
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 new ScriptTask()
                     .description("yarn install in Build/ dir")
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -1053,16 +1155,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job for unit testing PHP
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobUnitPhp(String requirementIdentifier) {
-        return new Job("Unit " + requirementIdentifier, new BambooKey("UT" + requirementIdentifier))
+    protected Job getJobUnitPhp(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Unit " + stageNumber + " " + requirementIdentifier, new BambooKey("UT" + stageNumber + requirementIdentifier))
             .description("Run unit tests " + requirementIdentifier)
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 new ScriptTask()
                     .description("Run phpunit")
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -1096,16 +1200,18 @@ abstract public class AbstractCoreSpec {
     /**
      * Job for unit testing deprecated PHP
      *
+     * @param int stageNumber
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected Job getJobUnitDeprecatedPhp(String requirementIdentifier) {
-        return new Job("Unit deprecated " + requirementIdentifier, new BambooKey("UTD" + requirementIdentifier))
+    protected Job getJobUnitDeprecatedPhp(int stageNumber, String requirementIdentifier, Task composerTask) {
+        return new Job("Unit deprecated " + stageNumber + " " + requirementIdentifier, new BambooKey("UTD" + stageNumber + requirementIdentifier))
             .description("Run deprecated unit tests " + requirementIdentifier)
             .pluginConfigurations(this.getDefaultJobPluginConfiguration())
             .tasks(
                 this.getTaskGitCloneRepository(),
                 this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
+                composerTask,
                 new ScriptTask()
                     .description("Run phpunit")
                     .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -1139,20 +1245,22 @@ abstract public class AbstractCoreSpec {
     /**
      * Jobs for unit testing PHP in random test order
      *
+     * @param int stageNumber
      * @param int numberOfRuns
      * @param String requirementIdentifier
+     * @param Task composerTask
      */
-    protected ArrayList<Job> getJobUnitPhpRandom(int numberOfRuns, String requirementIdentifier) {
+    protected ArrayList<Job> getJobUnitPhpRandom(int stageNumber, int numberOfRuns, String requirementIdentifier, Task composerTask) {
         ArrayList<Job> jobs = new ArrayList<Job>();
 
         for (int i=1; i<=numberOfRuns; i++) {
-            jobs.add(new Job("Unit " + requirementIdentifier + " random " + i, new BambooKey("UTR" + requirementIdentifier + i))
+            jobs.add(new Job("Unit " + stageNumber + " " + requirementIdentifier + " random " + i, new BambooKey("UTR" + stageNumber + requirementIdentifier + i))
                 .description("Run unit tests on " + requirementIdentifier + " in random order 0" + i)
                 .pluginConfigurations(this.getDefaultJobPluginConfiguration())
                 .tasks(
                     this.getTaskGitCloneRepository(),
                     this.getTaskGitCherryPick(),
-                    this.getTaskComposerInstall(requirementIdentifier),
+                    composerTask,
                     new ScriptTask()
                         .description("Run phpunit-randomizer")
                         .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
@@ -1232,6 +1340,30 @@ abstract public class AbstractCoreSpec {
             .environmentVariables(this.composerRootVersionEnvironment);
     }
 
+    /**
+     * Task definition to execute 'composer update --with-dependencies'.
+     * This will update all dependencies to current possible maximum version.
+     * Used in nightly to see if we are compatible with updates from dependencies.
+     *
+     * We update in 2 steps: First composer install as usual, then update. This
+     * way it is easy to see which packages are updated in comparison to what is
+     * currently defined in composer.lock.
+     *
+     * @param String requirementIdentifier
+     */
+    protected Task getTaskComposerUpdateMax(String requirementIdentifier) {
+        return new ScriptTask()
+            .description("composer update --with-dependencies")
+            .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
+            .inlineBody(
+                this.getScriptTaskBashInlineBody() +
+                this.getScriptTaskComposer(requirementIdentifier) +
+                "composer install -n\n" +
+                "composer update --with-dependencies -n"
+            )
+            .environmentVariables(this.composerRootVersionEnvironment);
+    }
+
     /**
      * Task to prepare an acceptance test
      */
diff --git a/Build/bamboo/src/main/java/core/NightlySpec.java b/Build/bamboo/src/main/java/core/NightlySpec.java
index 383613761368eb17337ec1ba2aa3abeee540710b..943db82078bd21a28b739079fa3a9cf3c27b2960 100644
--- a/Build/bamboo/src/main/java/core/NightlySpec.java
+++ b/Build/bamboo/src/main/java/core/NightlySpec.java
@@ -72,49 +72,81 @@ public class NightlySpec extends AbstractCoreSpec {
         Stage stagePreparation = new Stage("Preparation")
             .jobs(jobsPreparationStage.toArray(new Job[jobsPreparationStage.size()]));
 
+
         // MAIN stage
         ArrayList<Job> jobsMainStage = new ArrayList<Job>();
 
         jobsMainStage.add(this.getJobComposerValidate("PHP72"));
 
-        jobsMainStage.add(this.getJobAcceptanceTestInstallMysql("PHP72"));
-        jobsMainStage.add(this.getJobAcceptanceTestInstallPgsql("PHP72"));
-        jobsMainStage.add(this.getJobAcceptanceTestInstallSqlite("PHP72"));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallMysql(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallPgsql(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallSqlite(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.addAll(this.getJobsAcceptanceTestsBackendMysql(this.numberOfAcceptanceTestJobs, "PHP72"));
+        jobsMainStage.addAll(this.getJobsAcceptanceTestsBackendMysql(0, this.numberOfAcceptanceTestJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobCglCheckFullCore("PHP72"));
+        jobsMainStage.add(this.getJobCglCheckFullCore(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobIntegrationAnnotations("PHP72"));
+        jobsMainStage.add(this.getJobIntegrationAnnotations(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobIntegrationVarious("PHP72"));
+        jobsMainStage.add(this.getJobIntegrationVarious(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.addAll(this.getJobsFunctionalTestsMysql(this.numberOfFunctionalMysqlJobs, "PHP72"));
-        jobsMainStage.addAll(this.getJobsFunctionalTestsMssql(this.numberOfFunctionalMssqlJobs, "PHP72"));
-        jobsMainStage.addAll(this.getJobsFunctionalTestsPgsql(this.numberOfFunctionalPgsqlJobs, "PHP72"));
-        jobsMainStage.addAll(this.getJobsFunctionalTestsSqlite(this.numberOfFunctionalSqliteJobs, "PHP72"));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsMysql(0, this.numberOfFunctionalMysqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsMssql(0, this.numberOfFunctionalMssqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsPgsql(0, this.numberOfFunctionalPgsqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsSqlite(0, this.numberOfFunctionalSqliteJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobUnitJavaScript("PHP72"));
+        jobsMainStage.add(this.getJobUnitJavaScript(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
         jobsMainStage.add(this.getJobLintPhp("PHP72"));
 
         jobsMainStage.add(this.getJobLintScssTs("PHP72"));
 
-        jobsMainStage.add(this.getJobUnitPhp("PHP72"));
-        jobsMainStage.add(this.getJobUnitDeprecatedPhp("PHP72"));
-        jobsMainStage.addAll(this.getJobUnitPhpRandom(this.numberOfUnitRandomOrderJobs, "PHP72"));
+        jobsMainStage.add(this.getJobUnitPhp(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobUnitDeprecatedPhp(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobUnitPhpRandom(0, this.numberOfUnitRandomOrderJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
 
         Stage stageMainStage = new Stage("Main stage")
             .jobs(jobsMainStage.toArray(new Job[jobsMainStage.size()]));
 
 
+        // COMPOSER UPDATE MAX stage
+        ArrayList<Job> jobsComposerUpdateStage = new ArrayList<Job>();
+
+        jobsComposerUpdateStage.add(this.getJobAcceptanceTestInstallMysql(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.add(this.getJobAcceptanceTestInstallPgsql(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.add(this.getJobAcceptanceTestInstallSqlite(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.addAll(this.getJobsAcceptanceTestsBackendMysql(1, this.numberOfAcceptanceTestJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.add(this.getJobCglCheckFullCore(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.add(this.getJobIntegrationAnnotations(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.add(this.getJobIntegrationVarious(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.addAll(this.getJobsFunctionalTestsMysql(1, this.numberOfFunctionalMysqlJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.addAll(this.getJobsFunctionalTestsMssql(1, this.numberOfFunctionalMssqlJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.addAll(this.getJobsFunctionalTestsPgsql(1, this.numberOfFunctionalPgsqlJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.addAll(this.getJobsFunctionalTestsSqlite(1, this.numberOfFunctionalSqliteJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.add(this.getJobUnitJavaScript(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        jobsComposerUpdateStage.add(this.getJobUnitPhp(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.add(this.getJobUnitDeprecatedPhp(1, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+        jobsComposerUpdateStage.addAll(this.getJobUnitPhpRandom(1, this.numberOfUnitRandomOrderJobs, "PHP72", this.getTaskComposerUpdateMax("PHP72")));
+
+        Stage stageComposerUpdateStage = new Stage("Composer update max")
+            .jobs(jobsComposerUpdateStage.toArray(new Job[jobsComposerUpdateStage.size()]));
+
+
         // Compile plan
         return new Plan(project(), planName, planKey)
             .description("Execute TYPO3 core master nightly tests. Auto generated! See Build/bamboo of core git repository.")
             .pluginConfigurations(this.getDefaultPlanPluginConfiguration())
             .stages(
                 stagePreparation,
-                stageMainStage
+                stageMainStage,
+                stageComposerUpdateStage
             )
             .linkedRepositories("github TYPO3 TYPO3.CMS")
             .triggers(
@@ -134,43 +166,4 @@ public class NightlySpec extends AbstractCoreSpec {
                     .notificationForCommitters()
             );
     }
-
-    /**
-     * Job checking CGL of all core php files
-     *
-     * @param String requirementIdentifier
-     */
-    protected Job getJobCglCheckFullCore(String requirementIdentifier) {
-        return new Job("Integration CGL", new BambooKey("CGLCHECK"))
-            .description("Check coding guidelines of full core")
-            .pluginConfigurations(this.getDefaultJobPluginConfiguration())
-            .tasks(
-                this.getTaskGitCloneRepository(),
-                this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
-                new ScriptTask()
-                    .description("Execute cgl check")
-                    .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
-                    .inlineBody(
-                        this.getScriptTaskBashInlineBody() +
-                        "function phpCsFixer() {\n" +
-                        "    docker run \\\n" +
-                        "        -u ${HOST_UID} \\\n" +
-                        "        -v /bamboo-data/${BAMBOO_COMPOSE_PROJECT_NAME}/passwd:/etc/passwd \\\n" +
-                        "        -v ${BAMBOO_COMPOSE_PROJECT_NAME}_bamboo-data:/srv/bamboo/xml-data/build-dir/ \\\n" +
-                        "        --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" +
-                        "        --rm \\\n" +
-                        "        typo3gmbh/" + requirementIdentifier.toLowerCase() + ":latest \\\n" +
-                        "        bin/bash -c \"cd ${PWD}; php -n -c /etc/php/cli-no-xdebug/php.ini bin/php-cs-fixer $*\"\n" +
-                        "}\n" +
-                        "\n" +
-                        "phpCsFixer fix -v --dry-run --path-mode intersection --config=Build/.php_cs typo3/\n" +
-                        "exit $?"
-                    )
-            )
-            .requirements(
-                this.getRequirementDocker10()
-            )
-            .cleanWorkingDirectory(true);
-    }
 }
diff --git a/Build/bamboo/src/main/java/core/PreMergeSpec.java b/Build/bamboo/src/main/java/core/PreMergeSpec.java
index 870c1f8ff232aec38de7b384e454e30585c6230b..bec66191d7df397bf5fb673a150119c46435e9d3 100644
--- a/Build/bamboo/src/main/java/core/PreMergeSpec.java
+++ b/Build/bamboo/src/main/java/core/PreMergeSpec.java
@@ -88,31 +88,31 @@ public class PreMergeSpec extends AbstractCoreSpec {
         // MAIN stage
         ArrayList<Job> jobsMainStage = new ArrayList<Job>();
 
-        jobsMainStage.add(this.getJobAcceptanceTestInstallMysql("PHP72"));
-        jobsMainStage.add(this.getJobAcceptanceTestInstallPgsql("PHP72"));
-        jobsMainStage.add(this.getJobAcceptanceTestInstallSqlite("PHP72"));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallMysql(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallPgsql(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobAcceptanceTestInstallSqlite(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.addAll(this.getJobsAcceptanceTestsBackendMysql(this.numberOfAcceptanceTestJobs, "PHP72"));
+        jobsMainStage.addAll(this.getJobsAcceptanceTestsBackendMysql(0, this.numberOfAcceptanceTestJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobIntegrationAnnotations("PHP72"));
+        jobsMainStage.add(this.getJobIntegrationAnnotations(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobIntegrationVarious("PHP72"));
+        jobsMainStage.add(this.getJobIntegrationVarious(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.addAll(this.getJobsFunctionalTestsMysql(this.numberOfFunctionalMysqlJobs, "PHP72"));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsMysql(0, this.numberOfFunctionalMysqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
         // mssql functionals are not executed as pre-merge
-        // jobsMainStage.addAll(this.getJobsFunctionalTestsMssql(this.numberOfFunctionalMssqlJobs, "PHP72"));
-        jobsMainStage.addAll(this.getJobsFunctionalTestsPgsql(this.numberOfFunctionalPgsqlJobs, "PHP72"));
-        jobsMainStage.addAll(this.getJobsFunctionalTestsSqlite(this.numberOfFunctionalSqliteJobs, "PHP72"));
+        // jobsMainStage.addAll(this.getJobsFunctionalTestsMssql(0, this.numberOfFunctionalMssqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsPgsql(0, this.numberOfFunctionalPgsqlJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobsFunctionalTestsSqlite(0, this.numberOfFunctionalSqliteJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
 
-        jobsMainStage.add(this.getJobUnitJavaScript("PHP72"));
+        jobsMainStage.add(this.getJobUnitJavaScript(0, "PHP72", this.getTaskComposerInstall("PHP72")));
 
         jobsMainStage.add(this.getJobLintPhp("PHP72"));
 
         jobsMainStage.add(this.getJobLintScssTs("PHP72"));
 
-        jobsMainStage.add(this.getJobUnitPhp("PHP72"));
-        jobsMainStage.add(this.getJobUnitDeprecatedPhp("PHP72"));
-        jobsMainStage.addAll(this.getJobUnitPhpRandom(this.numberOfUnitRandomOrderJobs, "PHP72"));
+        jobsMainStage.add(this.getJobUnitPhp(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.add(this.getJobUnitDeprecatedPhp(0, "PHP72", this.getTaskComposerInstall("PHP72")));
+        jobsMainStage.addAll(this.getJobUnitPhpRandom(0, this.numberOfUnitRandomOrderJobs, "PHP72", this.getTaskComposerInstall("PHP72")));
 
         Stage stageMainStage = new Stage("Main stage")
             .jobs(jobsMainStage.toArray(new Job[jobsMainStage.size()]));
@@ -150,42 +150,4 @@ public class PreMergeSpec extends AbstractCoreSpec {
                 )
         );
     }
-
-    /**
-     * Job checking CGL of last git commit
-     *
-     * @param String requirementIdentifier
-     */
-    protected Job getJobCglCheckGitCommit(String requirementIdentifier) {
-        return new Job("Integration CGL", new BambooKey("CGLCHECK"))
-            .description("Check coding guidelines by executing Build/Scripts/cglFixMyCommit.sh script")
-            .pluginConfigurations(this.getDefaultJobPluginConfiguration())
-            .tasks(
-                this.getTaskGitCloneRepository(),
-                this.getTaskGitCherryPick(),
-                this.getTaskComposerInstall(requirementIdentifier),
-                new ScriptTask()
-                    .description("Execute cgl check script")
-                    .interpreter(ScriptTaskProperties.Interpreter.BINSH_OR_CMDEXE)
-                    .inlineBody(
-                        this.getScriptTaskBashInlineBody() +
-                        "function cglFixMyCommit() {\n" +
-                        "    docker run \\\n" +
-                        "        -u ${HOST_UID} \\\n" +
-                        "        -v /bamboo-data/${BAMBOO_COMPOSE_PROJECT_NAME}/passwd:/etc/passwd \\\n" +
-                        "        -v ${BAMBOO_COMPOSE_PROJECT_NAME}_bamboo-data:/srv/bamboo/xml-data/build-dir/ \\\n" +
-                        "        --name ${BAMBOO_COMPOSE_PROJECT_NAME}sib_adhoc \\\n" +
-                        "        --rm \\\n" +
-                        "        typo3gmbh/" + requirementIdentifier.toLowerCase() + ":latest \\\n" +
-                        "        bin/bash -c \"cd ${PWD}; ./Build/Scripts/cglFixMyCommit.sh $*\"\n" +
-                        "}\n" +
-                        "\n" +
-                        "cglFixMyCommit dryrun\n"
-                    )
-            )
-            .requirements(
-                this.getRequirementDocker10()
-            )
-            .cleanWorkingDirectory(true);
-    }
 }