diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 34a7181b1e..09b7e0d68a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -22,7 +22,7 @@ jobs:
             matrix:
                 include:
                     - db: 'none'
-                      php: '7.1'
+                      php: '7.3'
                       NOTESTS: 1
 
         name: PHP ${{ matrix.php }} - ${{ matrix.db }}
@@ -37,7 +37,7 @@ jobs:
               uses: shivammathur/setup-php@v2
               with:
                   php-version: ${{ matrix.php }}
-                  extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
+                  extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv
                   coverage: none
 
             - name: Get Composer Cache Directory
@@ -95,30 +95,26 @@ jobs:
         strategy:
             matrix:
                 include:
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mariadb:10.1"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mariadb:10.2"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mariadb:10.3"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mariadb:10.4"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mariadb:10.5"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mysql:5.6"
                       db_alias: "MySQL Slow Tests"
                       SLOWTESTS: 1
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mysql:5.6"
                       db_alias: "MyISAM Tests"
                       MYISAM: 1
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "mysql:5.6"
-                    - php: '7.1'
-                      db: "mysql:5.7"
-                    - php: '7.2'
-                      db: "mysql:5.7"
                     - php: '7.3'
                       db: "mysql:5.7"
                     - php: '7.4'
@@ -172,7 +168,7 @@ jobs:
               uses: shivammathur/setup-php@v2
               with:
                   php-version: ${{ matrix.php }}
-                  extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
+                  extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, mysqli, pdo, pdo_mysql, ldap
                   coverage: none
 
             - name: Get Composer Cache Directory
@@ -235,17 +231,17 @@ jobs:
         strategy:
             matrix:
                 include:
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:9.5"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:9.6"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:10"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:11"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:12"
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "postgres:13"
 
         name: PHP ${{ matrix.php }} - ${{ matrix.db }}
@@ -292,7 +288,7 @@ jobs:
               uses: shivammathur/setup-php@v2
               with:
                   php-version: ${{ matrix.php }}
-                  extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
+                  extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, pgsql, pdo, pdo_pgsql
                   coverage: none
 
             - name: Get Composer Cache Directory
@@ -338,12 +334,12 @@ jobs:
         strategy:
             matrix:
                 include:
-                    - php: '7.1'
+                    - php: '7.3'
                       db: "sqlite3"
-                    - php: '7.2'
+                    - php: '7.3'
                       db: "mcr.microsoft.com/mssql/server:2017-latest"
                       db_alias: 'MSSQL 2017'
-                    - php: '7.2'
+                    - php: '7.3'
                       db: "mcr.microsoft.com/mssql/server:2019-latest"
                       db_alias: 'MSSQL 2019'
 
@@ -395,7 +391,7 @@ jobs:
               uses: shivammathur/setup-php@v2
               with:
                   php-version: ${{ matrix.php }}
-                  extensions: dom, curl, libxml, mbstring, zip, pcntl, pdo, mysqli, sqlite, pdo_sqlite, intl, gd, exif, iconv, sqlsrv, pdo_sqlsrv, ldap
+                  extensions: dom, curl, libxml, mbstring, zip, pcntl, intl, gd, exif, iconv, sqlsrv, pdo, pdo_sqlsrv
                   coverage: none
 
             - name: Get Composer Cache Directory
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 0581f5188e..21b0b5e7ba 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -25,14 +25,16 @@
 		"phpbb/phpbb-core": "self.version"
 	},
 	"require": {
-		"php": "^7.1.3",
+		"php": "^7.3 || ^8.0",
 		"ext-json": "*",
 		"ext-mbstring": "*",
+		"ext-pdo": "*",
 		"bantu/ini-get-wrapper": "~1.0",
 		"chita/topological_sort": "^3.0",
 		"composer/composer": "^2.0",
 		"composer/installers": "^1.9",
 		"composer/package-versions-deprecated": "^1.11",
+		"doctrine/dbal": "^3.0",
 		"google/recaptcha": "~1.1",
 		"guzzlehttp/guzzle": "~6.3",
 		"lusitanian/oauth": "^0.8.1",
@@ -73,7 +75,7 @@
 	},
 	"config": {
 		"platform": {
-			"php": "7.1.3"
+			"php": "7.3.0"
 		}
 	}
 }
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index 9c1fece69a..934bae5274 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "8436b462289aea75fb1758aeb17fdc4e",
+    "content-hash": "98c49df46e2368bee9696e5a87c82fcc",
     "packages": [
         {
             "name": "bantu/ini-get-wrapper",
@@ -700,6 +700,311 @@
             ],
             "time": "2020-11-13T08:04:11+00:00"
         },
+        {
+            "name": "doctrine/cache",
+            "version": "1.10.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/cache.git",
+                "reference": "13e3381b25847283a91948d04640543941309727"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727",
+                "reference": "13e3381b25847283a91948d04640543941309727",
+                "shasum": ""
+            },
+            "require": {
+                "php": "~7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/common": ">2.2,<2.4"
+            },
+            "require-dev": {
+                "alcaeus/mongo-php-adapter": "^1.1",
+                "doctrine/coding-standard": "^6.0",
+                "mongodb/mongodb": "^1.1",
+                "phpunit/phpunit": "^7.0",
+                "predis/predis": "~1.0"
+            },
+            "suggest": {
+                "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.9.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
+                }
+            ],
+            "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.",
+            "homepage": "https://www.doctrine-project.org/projects/cache.html",
+            "keywords": [
+                "abstraction",
+                "apcu",
+                "cache",
+                "caching",
+                "couchdb",
+                "memcached",
+                "php",
+                "redis",
+                "xcache"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/cache/issues",
+                "source": "https://github.com/doctrine/cache/tree/1.10.x"
+            },
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-07-07T18:54:01+00:00"
+        },
+        {
+            "name": "doctrine/dbal",
+            "version": "3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/dbal.git",
+                "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/dbal/zipball/ee6d1260d5cc20ec506455a585945d7bdb98662c",
+                "reference": "ee6d1260d5cc20ec506455a585945d7bdb98662c",
+                "shasum": ""
+            },
+            "require": {
+                "composer/package-versions-deprecated": "^1.11.99",
+                "doctrine/cache": "^1.0",
+                "doctrine/event-manager": "^1.0",
+                "php": "^7.3 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^8.1",
+                "jetbrains/phpstorm-stubs": "^2019.1",
+                "phpstan/phpstan": "^0.12.40",
+                "phpstan/phpstan-strict-rules": "^0.12.2",
+                "phpunit/phpunit": "^9.4",
+                "psalm/plugin-phpunit": "^0.10.0",
+                "symfony/console": "^2.0.5|^3.0|^4.0|^5.0",
+                "vimeo/psalm": "^3.17.2"
+            },
+            "suggest": {
+                "symfony/console": "For helpful console commands such as SQL execution and import of files."
+            },
+            "bin": [
+                "bin/doctrine-dbal"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\DBAL\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                }
+            ],
+            "description": "Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.",
+            "homepage": "https://www.doctrine-project.org/projects/dbal.html",
+            "keywords": [
+                "abstraction",
+                "database",
+                "db2",
+                "dbal",
+                "mariadb",
+                "mssql",
+                "mysql",
+                "oci8",
+                "oracle",
+                "pdo",
+                "pgsql",
+                "postgresql",
+                "queryobject",
+                "sasql",
+                "sql",
+                "sqlite",
+                "sqlserver",
+                "sqlsrv"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/dbal/issues",
+                "source": "https://github.com/doctrine/dbal/tree/3.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-11-15T18:20:41+00:00"
+        },
+        {
+            "name": "doctrine/event-manager",
+            "version": "1.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/event-manager.git",
+                "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f",
+                "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/common": "<2.9@dev"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^6.0",
+                "phpunit/phpunit": "^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Common\\": "lib/Doctrine/Common"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Guilherme Blanco",
+                    "email": "guilhermeblanco@gmail.com"
+                },
+                {
+                    "name": "Roman Borschel",
+                    "email": "roman@code-factory.org"
+                },
+                {
+                    "name": "Benjamin Eberlei",
+                    "email": "kontakt@beberlei.de"
+                },
+                {
+                    "name": "Jonathan Wage",
+                    "email": "jonwage@gmail.com"
+                },
+                {
+                    "name": "Johannes Schmitt",
+                    "email": "schmittjoh@gmail.com"
+                },
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com"
+                }
+            ],
+            "description": "The Doctrine Event Manager is a simple PHP event system that was built to be used with the various Doctrine projects.",
+            "homepage": "https://www.doctrine-project.org/projects/event-manager.html",
+            "keywords": [
+                "event",
+                "event dispatcher",
+                "event manager",
+                "event system",
+                "events"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/event-manager/issues",
+                "source": "https://github.com/doctrine/event-manager/tree/1.1.x"
+            },
+            "funding": [
+                {
+                    "url": "https://www.doctrine-project.org/sponsorship.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://www.patreon.com/phpdoctrine",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fevent-manager",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2020-05-29T18:28:51+00:00"
+        },
         {
             "name": "google/recaptcha",
             "version": "1.2.4",
@@ -1157,33 +1462,34 @@
         },
         {
             "name": "ocramius/proxy-manager",
-            "version": "2.1.1",
+            "version": "2.2.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Ocramius/ProxyManager.git",
-                "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7"
+                "reference": "4d154742e31c35137d5374c998e8f86b54db2e2f"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/e18ac876b2e4819c76349de8f78ccc8ef1554cd7",
-                "reference": "e18ac876b2e4819c76349de8f78ccc8ef1554cd7",
+                "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/4d154742e31c35137d5374c998e8f86b54db2e2f",
+                "reference": "4d154742e31c35137d5374c998e8f86b54db2e2f",
                 "shasum": ""
             },
             "require": {
-                "ocramius/package-versions": "^1.1.1",
-                "php": "^7.1.0",
-                "zendframework/zend-code": "^3.1.0"
+                "ocramius/package-versions": "^1.1.3",
+                "php": "^7.2.0",
+                "zendframework/zend-code": "^3.3.0"
             },
             "require-dev": {
-                "couscous/couscous": "^1.5.2",
+                "couscous/couscous": "^1.6.1",
                 "ext-phar": "*",
-                "humbug/humbug": "dev-master@DEV",
-                "nikic/php-parser": "^3.0.4",
+                "humbug/humbug": "1.0.0-RC.0@RC",
+                "nikic/php-parser": "^3.1.1",
+                "padraic/phpunit-accelerator": "dev-master@DEV",
                 "phpbench/phpbench": "^0.12.2",
-                "phpstan/phpstan": "^0.6.4",
-                "phpunit/phpunit": "^5.6.4",
-                "phpunit/phpunit-mock-objects": "^3.4.1",
-                "squizlabs/php_codesniffer": "^2.7.0"
+                "phpstan/phpstan": "dev-master#856eb10a81c1d27c701a83f167dc870fd8f4236a as 0.9.999",
+                "phpstan/phpstan-phpunit": "dev-master#5629c0a1f4a9c417cb1077cf6693ad9753895761",
+                "phpunit/phpunit": "^6.4.3",
+                "squizlabs/php_codesniffer": "^2.9.1"
             },
             "suggest": {
                 "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects",
@@ -1224,9 +1530,9 @@
             ],
             "support": {
                 "issues": "https://github.com/Ocramius/ProxyManager/issues",
-                "source": "https://github.com/Ocramius/ProxyManager/tree/master"
+                "source": "https://github.com/Ocramius/ProxyManager/tree/2.2.x"
             },
-            "time": "2017-05-04T11:12:50+00:00"
+            "time": "2019-08-10T08:37:15+00:00"
         },
         {
             "name": "patchwork/utf8",
@@ -3438,20 +3744,20 @@
         },
         {
             "name": "twig/twig",
-            "version": "v2.13.1",
+            "version": "v2.14.3",
             "source": {
                 "type": "git",
                 "url": "https://github.com/twigphp/Twig.git",
-                "reference": "57e96259776ddcacf1814885fc3950460c8e18ef"
+                "reference": "8bc568d460d88b25c00c046256ec14a787ea60d9"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/twigphp/Twig/zipball/57e96259776ddcacf1814885fc3950460c8e18ef",
-                "reference": "57e96259776ddcacf1814885fc3950460c8e18ef",
+                "url": "https://api.github.com/repos/twigphp/Twig/zipball/8bc568d460d88b25c00c046256ec14a787ea60d9",
+                "reference": "8bc568d460d88b25c00c046256ec14a787ea60d9",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1.3",
+                "php": ">=7.2.5",
                 "symfony/polyfill-ctype": "^1.8",
                 "symfony/polyfill-mbstring": "^1.3"
             },
@@ -3462,7 +3768,7 @@
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.13-dev"
+                    "dev-master": "2.14-dev"
                 }
             },
             "autoload": {
@@ -3501,7 +3807,7 @@
             ],
             "support": {
                 "issues": "https://github.com/twigphp/Twig/issues",
-                "source": "https://github.com/twigphp/Twig/tree/v2.13.1"
+                "source": "https://github.com/twigphp/Twig/tree/v2.14.3"
             },
             "funding": [
                 {
@@ -3513,7 +3819,7 @@
                     "type": "tidelift"
                 }
             ],
-            "time": "2020-08-05T15:09:04+00:00"
+            "time": "2021-01-05T15:34:33+00:00"
         },
         {
             "name": "zendframework/zend-code",
@@ -4093,25 +4399,25 @@
         },
         {
             "name": "phpdocumentor/reflection-common",
-            "version": "2.1.0",
+            "version": "2.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
-                "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b"
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
-                "reference": "6568f4687e5b41b054365f9ae03fcb1ed5f2069b",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b",
+                "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": "^7.2 || ^8.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.x-dev"
+                    "dev-2.x": "2.x-dev"
                 }
             },
             "autoload": {
@@ -4140,47 +4446,43 @@
             ],
             "support": {
                 "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues",
-                "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master"
+                "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x"
             },
-            "time": "2020-04-27T09:25:28+00:00"
+            "time": "2020-06-27T09:03:43+00:00"
         },
         {
             "name": "phpdocumentor/reflection-docblock",
-            "version": "4.3.4",
+            "version": "5.2.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
-                "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c"
+                "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/da3fd972d6bafd628114f7e7e036f45944b62e9c",
-                "reference": "da3fd972d6bafd628114f7e7e036f45944b62e9c",
+                "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556",
+                "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.0",
-                "phpdocumentor/reflection-common": "^1.0.0 || ^2.0.0",
-                "phpdocumentor/type-resolver": "~0.4 || ^1.0.0",
-                "webmozart/assert": "^1.0"
+                "ext-filter": "*",
+                "php": "^7.2 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.2",
+                "phpdocumentor/type-resolver": "^1.3",
+                "webmozart/assert": "^1.9.1"
             },
             "require-dev": {
-                "doctrine/instantiator": "^1.0.5",
-                "mockery/mockery": "^1.0",
-                "phpdocumentor/type-resolver": "0.4.*",
-                "phpunit/phpunit": "^6.4"
+                "mockery/mockery": "~1.3.2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "4.x-dev"
+                    "dev-master": "5.x-dev"
                 }
             },
             "autoload": {
                 "psr-4": {
-                    "phpDocumentor\\Reflection\\": [
-                        "src/"
-                    ]
+                    "phpDocumentor\\Reflection\\": "src"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -4191,42 +4493,44 @@
                 {
                     "name": "Mike van Riel",
                     "email": "me@mikevanriel.com"
+                },
+                {
+                    "name": "Jaap van Otterdijk",
+                    "email": "account@ijaap.nl"
                 }
             ],
             "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
             "support": {
                 "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues",
-                "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x"
+                "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/master"
             },
-            "time": "2019-12-28T18:55:12+00:00"
+            "time": "2020-09-03T19:13:55+00:00"
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.0.1",
+            "version": "1.4.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9"
+                "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
-                "reference": "2e32a6d48972b2c1976ed5d8967145b6cec4a4a9",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
+                "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1",
+                "php": "^7.2 || ^8.0",
                 "phpdocumentor/reflection-common": "^2.0"
             },
             "require-dev": {
-                "ext-tokenizer": "^7.1",
-                "mockery/mockery": "~1",
-                "phpunit/phpunit": "^7.0"
+                "ext-tokenizer": "*"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.x-dev"
+                    "dev-1.x": "1.x-dev"
                 }
             },
             "autoload": {
@@ -4247,39 +4551,39 @@
             "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names",
             "support": {
                 "issues": "https://github.com/phpDocumentor/TypeResolver/issues",
-                "source": "https://github.com/phpDocumentor/TypeResolver/tree/0.7.2"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.4.0"
             },
-            "time": "2019-08-22T18:11:29+00:00"
+            "time": "2020-09-17T18:55:26+00:00"
         },
         {
             "name": "phpspec/prophecy",
-            "version": "v1.10.3",
+            "version": "1.12.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpspec/prophecy.git",
-                "reference": "451c3cd1418cf640de218914901e51b064abb093"
+                "reference": "245710e971a030f42e08f4912863805570f23d39"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093",
-                "reference": "451c3cd1418cf640de218914901e51b064abb093",
+                "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39",
+                "reference": "245710e971a030f42e08f4912863805570f23d39",
                 "shasum": ""
             },
             "require": {
-                "doctrine/instantiator": "^1.0.2",
-                "php": "^5.3|^7.0",
-                "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0",
-                "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0",
-                "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0"
+                "doctrine/instantiator": "^1.2",
+                "php": "^7.2 || ~8.0, <8.1",
+                "phpdocumentor/reflection-docblock": "^5.2",
+                "sebastian/comparator": "^3.0 || ^4.0",
+                "sebastian/recursion-context": "^3.0 || ^4.0"
             },
             "require-dev": {
-                "phpspec/phpspec": "^2.5 || ^3.2",
-                "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1"
+                "phpspec/phpspec": "^6.0",
+                "phpunit/phpunit": "^8.0 || ^9.0"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.10.x-dev"
+                    "dev-master": "1.11.x-dev"
                 }
             },
             "autoload": {
@@ -4314,9 +4618,9 @@
             ],
             "support": {
                 "issues": "https://github.com/phpspec/prophecy/issues",
-                "source": "https://github.com/phpspec/prophecy/tree/v1.10.3"
+                "source": "https://github.com/phpspec/prophecy/tree/1.12.2"
             },
-            "time": "2020-03-05T15:02:03+00:00"
+            "time": "2020-12-19T10:15:11+00:00"
         },
         {
             "name": "phpunit/dbunit",
@@ -5679,23 +5983,23 @@
         },
         {
             "name": "theseer/tokenizer",
-            "version": "1.1.3",
+            "version": "1.2.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/theseer/tokenizer.git",
-                "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9"
+                "reference": "75a63c33a8577608444246075ea0af0d052e452a"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
-                "reference": "11336f6f84e16a720dae9d8e6ed5019efa85a0f9",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a",
+                "reference": "75a63c33a8577608444246075ea0af0d052e452a",
                 "shasum": ""
             },
             "require": {
                 "ext-dom": "*",
                 "ext-tokenizer": "*",
                 "ext-xmlwriter": "*",
-                "php": "^7.0"
+                "php": "^7.2 || ^8.0"
             },
             "type": "library",
             "autoload": {
@@ -5719,7 +6023,13 @@
                 "issues": "https://github.com/theseer/tokenizer/issues",
                 "source": "https://github.com/theseer/tokenizer/tree/master"
             },
-            "time": "2019-06-13T22:48:21+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-07-12T23:59:07+00:00"
         },
         {
             "name": "webmozart/assert",
@@ -5781,13 +6091,13 @@
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
-        "php": "^7.1.3",
+        "php": ">=7.3.0",
         "ext-json": "*",
         "ext-mbstring": "*"
     },
     "platform-dev": [],
     "platform-overrides": {
-        "php": "7.1.3"
+        "php": "7.3.0"
     },
     "plugin-api-version": "2.0.0"
 }
diff --git a/phpBB/config/installer/container/services_install_data.yml b/phpBB/config/installer/container/services_install_data.yml
index 5de00170e9..c387a9f460 100644
--- a/phpBB/config/installer/container/services_install_data.yml
+++ b/phpBB/config/installer/container/services_install_data.yml
@@ -1,24 +1,37 @@
 services:
+    installer.install_data.add_languages:
+        class: phpbb\install\module\install_data\task\add_languages
+        arguments:
+            - '@installer.helper.config'
+            - '@installer.helper.database'
+            - '@installer.helper.iohandler'
+            - '@installer.helper.container_factory'
+            - '@language.helper.language_file'
+        tags:
+            - { name: install_data_install, order: 1 }
+
+    installer.install_data.add_languages_to_profile_fields:
+        class: phpbb\install\module\install_data\task\setup_languages
+        arguments:
+            - '@installer.helper.config'
+            - '@installer.helper.database'
+            - '@installer.helper.iohandler'
+            - '@installer.helper.container_factory'
+        tags:
+            - { name: install_data_install, order: 2 }
+
     installer.install_data.add_bots:
         class: phpbb\install\module\install_data\task\add_bots
         arguments:
             - '@installer.helper.config'
+            - '@installer.helper.database'
             - '@installer.helper.iohandler'
             - '@installer.helper.container_factory'
             - '@language'
             - '%core.root_path%'
             - '%core.php_ext%'
         tags:
-            - { name: install_data_install, order: 20 }
-
-    installer.install_data.add_languages:
-        class: phpbb\install\module\install_data\task\add_languages
-        arguments:
-            - '@installer.helper.iohandler'
-            - '@installer.helper.container_factory'
-            - '@language.helper.language_file'
-        tags:
-            - { name: install_data_install, order: 10 }
+            - { name: install_data_install, order: 3 }
 
     installer.install_data.add_modules:
         class: phpbb\install\module\install_data\task\add_modules
@@ -27,17 +40,19 @@ services:
             - '@installer.helper.iohandler'
             - '@installer.helper.container_factory'
         tags:
-            - { name: install_data_install, order: 30 }
+            - { name: install_data_install, order: 4 }
 
     installer.install_data.create_search_index:
         class: phpbb\install\module\install_data\task\create_search_index
         arguments:
-            - '@config'
+            - '@installer.helper.config'
+            - '@installer.helper.database'
             - '@installer.helper.container_factory'
+            - '@installer.helper.iohandler'
             - '%core.root_path%'
             - '%core.php_ext%'
         tags:
-            - { name: install_data_install, order: 40 }
+            - { name: install_data_install, order: 5 }
 
     installer.module.data_install_collection:
         class: phpbb\di\ordered_service_collection
@@ -52,4 +67,4 @@ services:
         arguments:
             - '@installer.module.data_install_collection'
         tags:
-            - { name: installer_install_module, order: 50 }
+            - { name: installer_install_module, order: 5 }
diff --git a/phpBB/config/installer/container/services_install_database.yml b/phpBB/config/installer/container/services_install_database.yml
index 2203e3b751..14baed7e79 100644
--- a/phpBB/config/installer/container/services_install_database.yml
+++ b/phpBB/config/installer/container/services_install_database.yml
@@ -9,7 +9,7 @@ services:
             - '%core.php_ext%'
             - '%tables%'
         tags:
-            - { name: install_database_install, order: 10 }
+            - { name: install_database_install, order: 1 }
 
     installer.install_database.set_up_database:
         class: phpbb\install\module\install_database\task\set_up_database
@@ -20,7 +20,7 @@ services:
             - '@installer.helper.iohandler'
             - '%core.root_path%'
         tags:
-            - { name: install_database_install, order: 20 }
+            - { name: install_database_install, order: 2 }
 
     installer.install_database.add_tables:
         class: phpbb\install\module\install_database\task\add_tables
@@ -29,7 +29,7 @@ services:
             - '@installer.helper.database'
             - '%core.root_path%'
         tags:
-            - { name: install_database_install, order: 30 }
+            - { name: install_database_install, order: 3 }
 
     installer.install_database.add_default_data:
         class: phpbb\install\module\install_database\task\add_default_data
@@ -37,15 +37,15 @@ services:
             - '@installer.helper.database'
             - '@installer.helper.config'
             - '@installer.helper.iohandler'
-            - '@installer.helper.container_factory'
             - '@language'
             - '%core.root_path%'
         tags:
-            - { name: install_database_install, order: 40 }
+            - { name: install_database_install, order: 4 }
 
     installer.install_database.add_config_settings:
         class: phpbb\install\module\install_database\task\add_config_settings
         arguments:
+            - '@installer.helper.database'
             - '@filesystem'
             - '@installer.helper.config'
             - '@installer.helper.iohandler'
@@ -53,7 +53,18 @@ services:
             - '@language'
             - '%core.root_path%'
         tags:
-            - { name: install_database_install, order: 50 }
+            - { name: install_database_install, order: 5 }
+
+    installer.install_database.update_user_and_post_data:
+        class: phpbb\install\module\install_database\task\update_user_and_post_data
+        arguments:
+            - '@installer.helper.config'
+            - '@installer.helper.container_factory'
+            - '@installer.helper.database'
+            - '@installer.helper.iohandler'
+            - '@language'
+        tags:
+            - { name: install_database_install, order: 6 }
 
     installer.module.install_database_collection:
         class: phpbb\di\ordered_service_collection
@@ -68,4 +79,4 @@ services:
         arguments:
             - '@installer.module.install_database_collection'
         tags:
-            - { name: installer_install_module, order: 40 }
+            - { name: installer_install_module, order: 4 }
diff --git a/phpBB/config/installer/container/services_install_filesystem.yml b/phpBB/config/installer/container/services_install_filesystem.yml
index 65b2a6eddd..996e593d15 100644
--- a/phpBB/config/installer/container/services_install_filesystem.yml
+++ b/phpBB/config/installer/container/services_install_filesystem.yml
@@ -10,7 +10,7 @@ services:
             - '%core.php_ext%'
             - '%installer.create_config_file.options%'
         tags:
-            - { name: install_filesystem_install, order: 10 }
+            - { name: install_filesystem_install, order: 1 }
 
     installer.module.install_filesystem_collection:
         class: phpbb\di\ordered_service_collection
@@ -25,4 +25,4 @@ services:
         arguments:
             - '@installer.module.install_filesystem_collection'
         tags:
-            - { name: installer_install_module, order: 30 }
+            - { name: installer_install_module, order: 3 }
diff --git a/phpBB/config/installer/container/services_install_finish.yml b/phpBB/config/installer/container/services_install_finish.yml
index 6a46d8f9d9..b200118e11 100644
--- a/phpBB/config/installer/container/services_install_finish.yml
+++ b/phpBB/config/installer/container/services_install_finish.yml
@@ -5,17 +5,17 @@ services:
             - '@installer.helper.config'
             - '@installer.helper.container_factory'
         tags:
-            - { name: install_finish, order: 10 }
+            - { name: install_finish, order: 1 }
 
     installer.install_finish.install_extensions:
         class: phpbb\install\module\install_finish\task\install_extensions
         arguments:
             - '@installer.helper.container_factory'
             - '@installer.helper.config'
+            - '@installer.helper.database'
             - '@installer.helper.iohandler'
-            - '%core.root_path%'
         tags:
-            - { name: install_finish, order: 20 }
+            - { name: install_finish, order: 2 }
 
     installer.install_finish.notify_user:
         class: phpbb\install\module\install_finish\task\notify_user
@@ -26,7 +26,7 @@ services:
             - '%core.root_path%'
             - '%core.php_ext%'
         tags:
-            - { name: install_finish, order: 30 }
+            - { name: install_finish, order: 3 }
 
     installer.module.install_finish_collection:
         class: phpbb\di\ordered_service_collection
@@ -41,4 +41,4 @@ services:
         arguments:
             - '@installer.module.install_finish_collection'
         tags:
-            - { name: installer_install_module, order: 60 }
+            - { name: installer_install_module, order: 6 }
diff --git a/phpBB/config/installer/container/services_install_obtain_data.yml b/phpBB/config/installer/container/services_install_obtain_data.yml
index 010aba829d..04b6912853 100644
--- a/phpBB/config/installer/container/services_install_obtain_data.yml
+++ b/phpBB/config/installer/container/services_install_obtain_data.yml
@@ -5,16 +5,7 @@ services:
             - '@installer.helper.config'
             - '@installer.helper.iohandler'
         tags:
-            - { name: install_obtain_data, order: 10 }
-
-    installer.obtain_data.obtain_board_data:
-        class: phpbb\install\module\obtain_data\task\obtain_board_data
-        arguments:
-            - '@installer.helper.config'
-            - '@installer.helper.iohandler'
-            - '@language.helper.language_file'
-        tags:
-            - { name: install_obtain_data, order: 50 }
+            - { name: install_obtain_data, order: 1 }
 
     installer.obtain_data.obtain_database_data:
         class: phpbb\install\module\obtain_data\task\obtain_database_data
@@ -23,15 +14,7 @@ services:
             - '@installer.helper.config'
             - '@installer.helper.iohandler'
         tags:
-            - { name: install_obtain_data, order: 20 }
-
-    installer.obtain_data.obtain_email_data:
-        class: phpbb\install\module\obtain_data\task\obtain_email_data
-        arguments:
-            - '@installer.helper.config'
-            - '@installer.helper.iohandler'
-        tags:
-            - { name: install_obtain_data, order: 40 }
+            - { name: install_obtain_data, order: 2 }
 
     installer.obtain_data.obtain_server_data:
         class: phpbb\install\module\obtain_data\task\obtain_server_data
@@ -39,7 +22,24 @@ services:
             - '@installer.helper.config'
             - '@installer.helper.iohandler'
         tags:
-            - { name: install_obtain_data, order: 30 }
+            - { name: install_obtain_data, order: 3 }
+
+    installer.obtain_data.obtain_email_data:
+        class: phpbb\install\module\obtain_data\task\obtain_email_data
+        arguments:
+            - '@installer.helper.config'
+            - '@installer.helper.iohandler'
+        tags:
+            - { name: install_obtain_data, order: 4 }
+
+    installer.obtain_data.obtain_board_data:
+        class: phpbb\install\module\obtain_data\task\obtain_board_data
+        arguments:
+            - '@installer.helper.config'
+            - '@installer.helper.iohandler'
+            - '@language.helper.language_file'
+        tags:
+            - { name: install_obtain_data, order: 5 }
 
     installer.module.install_obtain_data_collection:
         class: phpbb\di\ordered_service_collection
@@ -56,4 +56,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_install_module, order: 20 }
+            - { name: installer_install_module, order: 2 }
diff --git a/phpBB/config/installer/container/services_install_requirements.yml b/phpBB/config/installer/container/services_install_requirements.yml
index c03eb1fb93..93d123a0e9 100644
--- a/phpBB/config/installer/container/services_install_requirements.yml
+++ b/phpBB/config/installer/container/services_install_requirements.yml
@@ -7,7 +7,7 @@ services:
             - '%core.root_path%'
             - '%core.php_ext%'
         tags:
-            - { name: installer_requirements, order: 10 }
+            - { name: installer_requirements, order: 1 }
 
     installer.requirements.check_server_environment:
         class: phpbb\install\module\requirements\task\check_server_environment
@@ -15,8 +15,8 @@ services:
             - '@installer.helper.database'
             - '@installer.helper.iohandler'
         tags:
-            - { name: installer_requirements, order: 20 }
-            - { name: update_requirements, order: 20 }
+            - { name: installer_requirements, order: 2 }
+            - { name: update_requirements, order: 2 }
 
     installer.module.install_requirements_collection:
         class: phpbb\di\ordered_service_collection
@@ -34,4 +34,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_install_module, order: 10 }
+            - { name: installer_install_module, order: 1 }
diff --git a/phpBB/config/installer/container/services_update_database.yml b/phpBB/config/installer/container/services_update_database.yml
index bb97cff489..836b943670 100644
--- a/phpBB/config/installer/container/services_update_database.yml
+++ b/phpBB/config/installer/container/services_update_database.yml
@@ -37,4 +37,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_update_module, order: 40 }
+            - { name: installer_update_module, order: 4 }
diff --git a/phpBB/config/installer/container/services_update_filesystem.yml b/phpBB/config/installer/container/services_update_filesystem.yml
index cd9058bd3f..1dce58eaad 100644
--- a/phpBB/config/installer/container/services_update_filesystem.yml
+++ b/phpBB/config/installer/container/services_update_filesystem.yml
@@ -68,4 +68,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_update_module, order: 30 }
+            - { name: installer_update_module, order: 3 }
diff --git a/phpBB/config/installer/container/services_update_obtain_data.yml b/phpBB/config/installer/container/services_update_obtain_data.yml
index 999976aed0..37eb66ae01 100644
--- a/phpBB/config/installer/container/services_update_obtain_data.yml
+++ b/phpBB/config/installer/container/services_update_obtain_data.yml
@@ -50,4 +50,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_update_module, order: 20 }
+            - { name: installer_update_module, order: 2 }
diff --git a/phpBB/config/installer/container/services_update_requirements.yml b/phpBB/config/installer/container/services_update_requirements.yml
index 6b851de78b..7ca7c921d1 100644
--- a/phpBB/config/installer/container/services_update_requirements.yml
+++ b/phpBB/config/installer/container/services_update_requirements.yml
@@ -38,4 +38,4 @@ services:
             - true
             - false
         tags:
-            - { name: installer_update_module, order: 10 }
+            - { name: installer_update_module, order: 1 }
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index 4abc176d19..4986e3db8f 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -690,12 +690,6 @@ class acp_main
 			]);
 		}
 
-		// Fill dbms version if not yet filled
-		if (empty($config['dbms_version']))
-		{
-			$config->set('dbms_version', $db->sql_server_info(true));
-		}
-
 		$this->tpl_name = 'acp_main';
 		$this->page_title = 'ACP_MAIN';
 	}
diff --git a/phpBB/includes/questionnaire/questionnaire.php b/phpBB/includes/questionnaire/questionnaire.php
index 848a65956b..6792ae39b7 100644
--- a/phpBB/includes/questionnaire/questionnaire.php
+++ b/phpBB/includes/questionnaire/questionnaire.php
@@ -258,7 +258,7 @@ class phpbb_questionnaire_phpbb_data_provider
 		extract($phpbb_config_php_file->get_all());
 		unset($dbhost, $dbport, $dbname, $dbuser, $dbpasswd); // Just a precaution
 
-		$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
+		$dbms = \phpbb\config_php_file::convert_30_dbms_to_31($dbms);
 
 		// Only send certain config vars
 		$config_vars = array(
@@ -326,7 +326,6 @@ class phpbb_questionnaire_phpbb_data_provider
 			'cookie_secure' => true,
 			'coppa_enable' => true,
 			'database_gc' => true,
-			'dbms_version' => true,
 			'default_dateformat' => true,
 			'default_lang' => true,
 			'display_last_edited' => true,
diff --git a/phpBB/install/convert/controller/convertor.php b/phpBB/install/convert/controller/convertor.php
index b764171422..9b44832dfe 100644
--- a/phpBB/install/convert/controller/convertor.php
+++ b/phpBB/install/convert/controller/convertor.php
@@ -493,7 +493,7 @@ class convertor
 			$error[] = $this->language->lang('INST_ERR_DB_CONNECT');
 		}
 
-		$src_dbms = $this->config_php_file->convert_30_dbms_to_31($src_dbms);
+		$src_dbms = \phpbb\config_php_file::convert_30_dbms_to_31($src_dbms);
 
 		// Check table prefix
 		if (empty($error))
diff --git a/phpBB/install/convert/convertor.php b/phpBB/install/convert/convertor.php
index 52a4565083..f8196d73a1 100644
--- a/phpBB/install/convert/convertor.php
+++ b/phpBB/install/convert/convertor.php
@@ -71,7 +71,7 @@ class convertor
 		require_once($phpbb_root_path . 'includes/constants.' . $phpEx);
 		require_once($phpbb_root_path . 'includes/functions_convert.' . $phpEx);
 
-		$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
+		$dbms = \phpbb\config_php_file::convert_30_dbms_to_31($dbms);
 
 		/** @var \phpbb\db\driver\driver_interface $db */
 		$db = new $dbms();
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 57e0710fa0..50518b7b3b 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -29,7 +29,7 @@ $phpbb_config_php_file = new \phpbb\config_php_file($phpbb_root_path, $phpEx);
 extract($phpbb_config_php_file->get_all());
 unset($dbpasswd);
 
-$dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
+$dbms = \phpbb\config_php_file::convert_30_dbms_to_31($dbms);
 
 /**
 * $convertor_data provides some basic information about this convertor which is
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 44987f2662..e6a3187a79 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -66,6 +66,7 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_form',
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_email_sig', '{L_CONFIG_BOARD_EMAIL_SIG}');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_hide_emails', '1');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_index_text', '');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_startdate', '0');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_timezone', 'UTC');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('browser_check', '1');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('bump_interval', '10');
@@ -93,8 +94,8 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_enable', '0'
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_fax', '');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('coppa_mail', '');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('database_gc', '604800');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('dbms_version', '');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_dateformat', 'D M d, Y g:i a');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_lang', 'en');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_search_return_chars', '300');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('default_style', '1');
 INSERT INTO phpbb_config (config_name, config_value) VALUES ('delete_time', '0');
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 0b94a3cd38..9f31f87078 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -182,6 +182,7 @@ $lang = array_merge($lang, array(
 	'CONGRATULATIONS'		=> 'Congratulations to',
 	'CONNECTION_FAILED'		=> 'Connection failed.',
 	'CONNECTION_SUCCESS'	=> 'Connection was successful!',
+	'DB_CONNECTION_FAILED'	=> 'Connecting to the database failed.',
 	'CONTACT'				=> 'Contact',
 	'CONTACT_USER'			=> 'Contact %s',
 	'CONTACT_US'			=> 'Contact us',
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 13f926f8db..7eda9908f4 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -294,6 +294,7 @@ $lang = array_merge($lang, array(
 
 	// Install database
 	'TASK_ADD_CONFIG_SETTINGS'			=> 'Adding configuration settings',
+	'TASK_UPDATE_POSTS'					=> 'Adding default forums, topics and posts',
 	'TASK_ADD_DEFAULT_DATA'				=> 'Adding default settings to the database',
 	'TASK_CREATE_DATABASE_SCHEMA_FILE'	=> 'Creating database schema file',
 	'TASK_SETUP_DATABASE'				=> 'Setting up database',
@@ -302,6 +303,7 @@ $lang = array_merge($lang, array(
 	// Install data
 	'TASK_ADD_BOTS'				=> 'Registering bots',
 	'TASK_ADD_LANGUAGES'		=> 'Installing available languages',
+	'TASK_SET_LANGUAGES'		=> 'Adding language profile fields',
 	'TASK_ADD_MODULES'			=> 'Installing modules',
 	'TASK_CREATE_SEARCH_INDEX'	=> 'Creating search index',
 
diff --git a/phpBB/phpbb/config_php_file.php b/phpBB/phpbb/config_php_file.php
index be17906ad1..e3eeef06f0 100644
--- a/phpBB/phpbb/config_php_file.php
+++ b/phpBB/phpbb/config_php_file.php
@@ -121,7 +121,7 @@ class config_php_file
 	* @return string driver class
 	* @throws \RuntimeException
 	*/
-	public function convert_30_dbms_to_31($dbms)
+	public static function convert_30_dbms_to_31($dbms)
 	{
 		// Note: this check is done first because mysqli extension
 		// supplies a mysqli class, and class_exists($dbms) would return
diff --git a/phpBB/phpbb/db/doctrine/connection_factory.php b/phpBB/phpbb/db/doctrine/connection_factory.php
new file mode 100644
index 0000000000..93c5b8c03e
--- /dev/null
+++ b/phpBB/phpbb/db/doctrine/connection_factory.php
@@ -0,0 +1,114 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\doctrine;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\DriverManager;
+use Doctrine\DBAL\Exception;
+use InvalidArgumentException;
+use phpbb\config_php_file;
+use phpbb\exception\runtime_exception;
+
+/**
+ * Doctrine DBAL connection factory.
+ */
+class connection_factory
+{
+	use driver_convertor;
+
+	/**
+	 * Creates a Doctrine DBAL connection from phpBB configuration.
+	 *
+	 * @param config_php_file $config Config PHP file wrapper.
+	 *
+	 * @return Connection Doctrine DBAL connection.
+	 *
+	 * @throws runtime_exception		If the database connection could not be established.
+	 * @throws InvalidArgumentException	If the provided driver name is not a valid phpBB database driver.
+	 */
+	public static function get_connection(config_php_file $config) : Connection
+	{
+		$driver = $config->get('dbms');
+		$host = $config->get('dbhost');
+		$user = $config->get('dbuser');
+		$pass = $config->get('dbpasswd');
+		$name = $config->get('dbname');
+		$port = $config->get('dbport');
+
+		return self::get_connection_from_params(
+			$driver,
+			$host,
+			$user,
+			$pass,
+			$name,
+			$port
+		);
+	}
+
+	/**
+	 * Creates a database connection from the specified parameters.
+	 *
+	 * @param string		$driver		Driver name.
+	 * @param string		$host		Hostname.
+	 * @param string|null	$user		Username.
+	 * @param string|null	$password	Password.
+	 * @param string|null	$name		Database name.
+	 * @param string|null	$port		Database port.
+	 *
+	 * @return Connection Doctrine DBAL connection.
+	 *
+	 * @throws runtime_exception		If the database connection could not be established.
+	 * @throws InvalidArgumentException	If $driver is not a valid phpBB database driver.
+	 */
+	public static function get_connection_from_params(
+		string $driver,
+		string $host,
+		?string $user = null,
+		?string $password = null,
+		?string $name = null,
+		?string $port = null) : Connection
+	{
+		$available_drivers = DriverManager::getAvailableDrivers();
+		if (!in_array($driver, $available_drivers))
+		{
+			$driver = config_php_file::convert_30_dbms_to_31($driver);
+			$driver = self::to_doctrine_driver($driver);
+		}
+
+		$params = connection_parameter_factory::get_configuration(
+			$driver,
+			$host,
+			$user,
+			$password,
+			$name,
+			$port
+		);
+
+		try
+		{
+			return DriverManager::getConnection($params);
+		}
+		catch (Exception $e)
+		{
+			throw new runtime_exception('DB_CONNECTION_FAILED');
+		}
+	}
+
+	/*
+	 * Disable constructor.
+	 */
+	private function __construct()
+	{
+	}
+}
diff --git a/phpBB/phpbb/db/doctrine/connection_parameter_factory.php b/phpBB/phpbb/db/doctrine/connection_parameter_factory.php
new file mode 100644
index 0000000000..203ab37b89
--- /dev/null
+++ b/phpBB/phpbb/db/doctrine/connection_parameter_factory.php
@@ -0,0 +1,180 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\doctrine;
+
+use InvalidArgumentException;
+
+/**
+ * Helper class to generate Doctrine DBAL configuration.
+ */
+class connection_parameter_factory
+{
+	/**
+	 * Returns configuration options for Doctrine DBAL.
+	 *
+	 * @param string		$driver		Driver name.
+	 * @param string		$host		Hostname.
+	 * @param string|null	$user		Username.
+	 * @param string|null	$password	Password.
+	 * @param string|null	$name		Database name.
+	 * @param string|null	$port		Database port.
+	 *
+	 * @return array Doctrine DBAL connection parameters.
+	 *
+	 * @throws InvalidArgumentException If a required parameter is empty or null.
+	 */
+	public static function get_configuration(
+		string $driver,
+		string $host,
+		?string $user = null,
+		?string $password = null,
+		?string $name = null,
+		?string $port = null) : array
+	{
+		$params = [
+			'driver' => $driver,
+		];
+
+		return self::build_connection_parameters(
+			$params,
+			$host,
+			$user,
+			$password,
+			$name,
+			$port
+		);
+	}
+
+	/**
+	 * Build Doctrine configuration array.
+	 *
+	 * @param array			$params		Parameter array.
+	 * @param string		$host		Database hostname.
+	 * @param string|null	$user		Username.
+	 * @param string|null	$password	Password.
+	 * @param string|null	$name		Database name.
+	 * @param string|null	$port		Database port.
+	 *
+	 * @return array Doctrine's DBAL configuration for SQLite.
+	 *
+	 * @throws InvalidArgumentException If a required parameter is empty or null.
+	 */
+	private static function build_connection_parameters(
+		array $params,
+		string $host,
+		?string $user = null,
+		?string $password = null,
+		?string $name = null,
+		?string $port = null) : array
+	{
+		if ($params['driver'] === 'pdo_sqlite')
+		{
+			return self::enrich_parameters(
+				self::build_sqlite_parameters($params, $host, $user, $password)
+			);
+		}
+
+		if (empty($host) || empty($user) || empty($name))
+		{
+			throw new InvalidArgumentException('Required database parameter is not set.');
+		}
+
+		$params = array_merge($params, [
+			'host'		=> $host,
+			'user'		=> $user,
+			'dbname'	=> $name,
+		]);
+
+		if (!empty($password))
+		{
+			$params['password'] = $password;
+		}
+
+		if (!empty($port))
+		{
+			$params['port'] = (int) $port;
+		}
+
+		return self::enrich_parameters($params);
+	}
+
+	/**
+	 * Build configuration array for SQLite.
+	 *
+	 * @param array			$params		Parameter array.
+	 * @param string		$path		Path to the database.
+	 * @param string|null	$user		Username.
+	 * @param string|null	$password	Password.
+	 *
+	 * @return array Doctrine's DBAL configuration for SQLite.
+	 */
+	private static function build_sqlite_parameters(array $params, string $path, ?string $user, ?string $password) : array
+	{
+		$params['path'] = $path;
+
+		if (!empty($user))
+		{
+			$params['user'] = $user;
+		}
+
+		if (!empty($password))
+		{
+			$params['password'] = $password;
+		}
+
+		return $params;
+	}
+
+	/**
+	 * Add additional configuration options to the parameter list.
+	 *
+	 * @param array $params	The parameter list to enrich.
+	 *
+	 * @return array The enriched parameter list.
+	 */
+	private static function enrich_parameters(array $params) : array
+	{
+		$enrichment_tags = [
+			'pdo_mysql' => [
+				'charset' => 'UTF8',
+			],
+			'oci8' => [
+				'charset' => 'UTF8',
+			],
+			'pdo_pgsql' => [
+				'charset' => 'UTF8',
+			],
+		];
+
+		if ($params['driver'] === 'pdo_mysql')
+		{
+			$enrichment_tags['pdo_mysql'][\PDO::MYSQL_ATTR_FOUND_ROWS] = true;
+		}
+
+		$driver = $params['driver'];
+		if (!array_key_exists($driver, $enrichment_tags))
+		{
+			return $params;
+		}
+
+		return array_merge($params, $enrichment_tags[$driver]);
+	}
+
+	/*
+	 * Disable constructing this class.
+	 */
+	private function __construct()
+	{
+	}
+}
diff --git a/phpBB/phpbb/db/doctrine/driver_convertor.php b/phpBB/phpbb/db/doctrine/driver_convertor.php
new file mode 100644
index 0000000000..b729b1065e
--- /dev/null
+++ b/phpBB/phpbb/db/doctrine/driver_convertor.php
@@ -0,0 +1,68 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\doctrine;
+
+use InvalidArgumentException;
+
+/**
+ * Driver convertor utility for Doctrine DBAL.
+ */
+trait driver_convertor
+{
+	/**
+	 * Converts phpBB driver names to Doctrine's equivalent.
+	 *
+	 * @param string $driver_name phpBB database driver name.
+	 *
+	 * @return string Doctrine DBAL's driver name.
+	 *
+	 * @throws InvalidArgumentException If $driver_name is not a valid phpBB database driver.
+	 */
+	public static function to_doctrine_driver(string $driver_name) : string
+	{
+		// Normalize driver name.
+		$name = str_replace('phpbb\db\driver', '', $driver_name);
+		$name = preg_replace('/mysql$/i', 'mysqli', $name);
+		$name = trim($name, '\\');
+
+		switch ($name)
+		{
+			case 'mssql_odbc':
+			case 'mssqlnative':
+				$name = 'pdo_sqlsrv';
+			break;
+
+			case 'mysqli':
+				$name = 'pdo_mysql';
+			break;
+
+			case 'oracle':
+				$name = 'oci8';
+			break;
+
+			case 'postgres':
+				$name = 'pdo_pgsql';
+			break;
+
+			case 'sqlite3':
+				$name = 'pdo_sqlite';
+			break;
+
+			default:
+				throw new InvalidArgumentException('Invalid phpBB database driver provided: ' . $driver_name);
+		}
+
+		return $name;
+	}
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/remove_dbms_version_config.php b/phpBB/phpbb/db/migration/data/v400/remove_dbms_version_config.php
new file mode 100644
index 0000000000..bc3f1a3c5a
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/remove_dbms_version_config.php
@@ -0,0 +1,38 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class remove_dbms_version_config extends migration
+{
+	public function effectively_installed()
+	{
+		return !$this->config->offsetExists('dbms_version');
+	}
+
+	public function update_data()
+	{
+		return [
+			['config.remove', ['dbms_version']],
+		];
+	}
+
+	static public function depends_on()
+	{
+		return [
+			'\phpbb\db\migration\data\v30x\release_3_0_3_rc1',
+		];
+	}
+}
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index e087ef834a..dfb29ed27c 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -572,7 +572,7 @@ class container_builder
 		{
 			if ($this->dbal_connection === null)
 			{
-				$dbal_driver_class = $this->config_php_file->convert_30_dbms_to_31($this->config_php_file->get('dbms'));
+				$dbal_driver_class = \phpbb\config_php_file::convert_30_dbms_to_31($this->config_php_file->get('dbms'));
 				/** @var \phpbb\db\driver\driver_interface $dbal_connection */
 				$this->dbal_connection = new $dbal_driver_class();
 				$this->dbal_connection->sql_connect(
diff --git a/phpBB/phpbb/install/database_task.php b/phpBB/phpbb/install/database_task.php
new file mode 100644
index 0000000000..81864773c5
--- /dev/null
+++ b/phpBB/phpbb/install/database_task.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\install;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Driver\Exception as DriverException;
+use Doctrine\DBAL\Driver\Statement as DriverStmt;
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Result;
+use Doctrine\DBAL\Statement;
+use phpbb\db\doctrine\connection_factory;
+use phpbb\install\helper\config;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+
+/**
+ * Abstract base class for common database manipulation tasks.
+ */
+abstract class database_task extends task_base
+{
+	/** @var Connection */
+	private $conn;
+
+	/** @var iohandler_interface */
+	private $io;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param Connection			$connection	Doctrine DBAL connection.
+	 * @param iohandler_interface	$io			IO handler to use.
+	 * @param bool					$essential	Whether the task is essential.
+	 */
+	public function __construct(Connection $connection, iohandler_interface $io, bool $essential = true)
+	{
+		$this->conn = $connection;
+		$this->io = $io;
+
+		parent::__construct($essential);
+	}
+
+	/**
+	 * Execute a SQL query.
+	 *
+	 * @param string $sql The SQL to execute.
+	 */
+	protected function exec_sql(string $sql)
+	{
+		try
+		{
+			$this->conn->executeStatement($sql);
+		}
+		catch (Exception $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+	}
+
+	/**
+	 * Run a query and return the result object.
+	 *
+	 * @param string $sql SQL query.
+	 *
+	 * @return Result|null Result of the query.
+	 */
+	protected function query(string $sql) : ?Result
+	{
+		try
+		{
+			return $this->conn->executeQuery($sql);
+		}
+		catch (Exception $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+
+		return null;
+	}
+
+	/**
+	 * Creates a prepared statement.
+	 *
+	 * @param string $sql The SQL.
+	 *
+	 * @return DriverStmt|Statement The prepared statement object.
+	 */
+	protected function create_prepared_stmt(string $sql)
+	{
+		try
+		{
+			return $this->conn->prepare($sql);
+		}
+		catch (Exception $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+
+		return null;
+	}
+
+	/**
+	 * Create and execute a prepared statement.
+	 *
+	 * @param string	$sql	The SQL to create the statement from.
+	 * @param array		$params	The parameters to bind to it.
+	 */
+	protected function create_and_execute_prepared_stmt(string $sql, array $params)
+	{
+		try
+		{
+			$stmt = $this->conn->prepare($sql);
+			$this->exec_prepared_stmt($stmt, $params);
+		}
+		catch (Exception $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+	}
+
+	/**
+	 * Bind values and execute a prepared statement.
+	 *
+	 * @param Statement|DriverStmt	$stmt	Prepared statement.
+	 * @param array					$params	Parameters.
+	 */
+	protected function exec_prepared_stmt($stmt, array $params)
+	{
+		try
+		{
+			foreach ($params as $name => $val)
+			{
+				$stmt->bindValue($name, $val);
+			}
+			$stmt->execute();
+		}
+		catch (DriverException $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+	}
+
+	/**
+	 * Returns the last insert ID.
+	 *
+	 * @return string|null The last insert ID.
+	 */
+	protected function get_last_insert_id() : ?string
+	{
+		try
+		{
+			return $this->conn->lastInsertId();
+		}
+		catch (Exception $e)
+		{
+			$this->report_error($e->getMessage());
+		}
+
+		return null;
+	}
+
+	/**
+	 * Report a database error.
+	 *
+	 * @param string $message The error message.
+	 */
+	private function report_error(string $message)
+	{
+		$this->io->add_error_message('INST_ERR_DB', $message);
+	}
+
+	/**
+	 * Create a Doctrine connection in the installer context.
+	 *
+	 * @param database	$db_helper	Database helper.
+	 * @param config	$config		Config options.
+	 *
+	 * @return Connection Doctrine DBAL connection object.
+	 */
+	protected static function get_doctrine_connection(database $db_helper, config $config) : Connection
+	{
+		$dbms = $db_helper->get_available_dbms($config->get('dbms'));
+		$dbms = $dbms[$config->get('dbms')]['DRIVER'];
+
+		return connection_factory::get_connection_from_params(
+			$dbms,
+			$config->get('dbhost'),
+			$config->get('dbuser'),
+			$config->get('dbpasswd'),
+			$config->get('dbname'),
+			$config->get('dbport')
+		);
+	}
+}
diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php
index f7d1ac39d2..04d4bbb9c9 100644
--- a/phpBB/phpbb/install/helper/database.php
+++ b/phpBB/phpbb/install/helper/database.php
@@ -41,24 +41,27 @@ class database
 			'LABEL'			=> 'MySQL with MySQLi Extension',
 			'SCHEMA'		=> 'mysql_41',
 			'MODULE'		=> 'mysqli',
+			'DOCTRINE'		=> ['pdo_mysql'],
 			'DELIM'			=> ';',
 			'DRIVER'		=> 'phpbb\db\driver\mysqli',
 			'AVAILABLE'		=> true,
 			'2.0.x'			=> true,
 		),
-		'mssql_odbc'=>	array(
+		'mssql_odbc'	=>	array(
 			'LABEL'			=> 'MS SQL Server [ ODBC ]',
 			'SCHEMA'		=> 'mssql',
 			'MODULE'		=> 'odbc',
+			'DOCTRINE'		=> ['pdo_sqlsrv'],
 			'DELIM'			=> ';',
 			'DRIVER'		=> 'phpbb\db\driver\mssql_odbc',
 			'AVAILABLE'		=> true,
 			'2.0.x'			=> true,
 		),
-		'mssqlnative'		=> array(
+		'mssqlnative'	=> array(
 			'LABEL'			=> 'MS SQL Server 2005+ [ Native ]',
 			'SCHEMA'		=> 'mssql',
 			'MODULE'		=> 'sqlsrv',
+			'DOCTRINE'		=> ['pdo_sqlsrv'],
 			'DELIM'			=> ';',
 			'DRIVER'		=> 'phpbb\db\driver\mssqlnative',
 			'AVAILABLE'		=> true,
@@ -77,6 +80,7 @@ class database
 			'LABEL'			=> 'PostgreSQL 8.3+',
 			'SCHEMA'		=> 'postgres',
 			'MODULE'		=> 'pgsql',
+			'DOCTRINE'		=> ['pdo_pgsql'],
 			'DELIM'			=> ';',
 			'DRIVER'		=> 'phpbb\db\driver\postgres',
 			'AVAILABLE'		=> true,
@@ -86,6 +90,7 @@ class database
 			'LABEL'			=> 'SQLite3',
 			'SCHEMA'		=> 'sqlite',
 			'MODULE'		=> 'sqlite3',
+			'DOCTRINE'		=> ['pdo_sqlite'],
 			'DELIM'			=> ';',
 			'DRIVER'		=> 'phpbb\db\driver\sqlite3',
 			'AVAILABLE'		=> true,
@@ -166,6 +171,33 @@ class database
 				continue;
 			}
 
+			if (array_key_exists('DOCTRINE', $db_array))
+			{
+				$available = false;
+				foreach ($db_array['DOCTRINE'] as $dll)
+				{
+					if (@extension_loaded($dll))
+					{
+						$available = true;
+						break;
+					}
+				}
+
+				if (!$available)
+				{
+					if ($return_unavailable)
+					{
+						$available_dbms[$db_name]['AVAILABLE'] = false;
+					}
+					else
+					{
+						unset($available_dbms[$db_name]);
+					}
+
+					continue;
+				}
+			}
+
 			$any_dbms_available = true;
 		}
 
diff --git a/phpBB/phpbb/install/module/install_data/task/add_bots.php b/phpBB/phpbb/install/module/install_data/task/add_bots.php
index e53087a671..d5ace8d22a 100644
--- a/phpBB/phpbb/install/module/install_data/task/add_bots.php
+++ b/phpBB/phpbb/install/module/install_data/task/add_bots.php
@@ -13,10 +13,21 @@
 
 namespace phpbb\install\module\install_data\task;
 
-use phpbb\install\exception\resource_limit_reached_exception;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Statement;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
+use phpbb\language\language;
 
-class add_bots extends \phpbb\install\task_base
+class add_bots extends database_task
 {
+	use sequential_task;
+
 	/**
 	 * A list of the web-crawlers/bots we recognise by default
 	 *
@@ -106,22 +117,17 @@ class add_bots extends \phpbb\install\task_base
 	);
 
 	/**
-	 * @var \phpbb\db\driver\driver_interface
-	 */
-	protected $db;
-
-	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $install_config;
 
 	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
+	 * @var iohandler_interface
 	 */
 	protected $io_handler;
 
 	/**
-	 * @var \phpbb\language\language
+	 * @var language
 	 */
 	protected $language;
 
@@ -135,31 +141,59 @@ class add_bots extends \phpbb\install\task_base
 	 */
 	protected $php_ext;
 
+	/**
+	 * @var string
+	 */
+	protected $groups_table;
+
+	/**
+	 * @var string
+	 */
+	protected $bots_table;
+
+	/**
+	 * @var DriverStatement|Statement
+	 */
+	protected $stmt;
+
+	/**
+	 * @var int
+	 */
+	protected $group_id;
+
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\config							$install_config		Installer's config
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler			Input-output handler for the installer
-	 * @param \phpbb\install\helper\container_factory				$container			Installer's DI container
-	 * @param \phpbb\language\language								$language			Language provider
-	 * @param string												$phpbb_root_path	Relative path to phpBB root
-	 * @param string												$php_ext			PHP extension
+	 * @param config				$install_config		Installer's config
+	 * @param database				$db_helper			Database helper.
+	 * @param iohandler_interface	$iohandler			Input-output handler for the installer
+	 * @param container_factory		$container			Installer's DI container
+	 * @param language				$language			Language provider
+	 * @param string				$phpbb_root_path	Relative path to phpBB root
+	 * @param string				$php_ext			PHP extension
 	 */
-	public function __construct(\phpbb\install\helper\config $install_config,
-								\phpbb\install\helper\iohandler\iohandler_interface $iohandler,
-								\phpbb\install\helper\container_factory $container,
-								\phpbb\language\language $language,
-								$phpbb_root_path,
-								$php_ext)
+	public function __construct(config $install_config,
+								database $db_helper,
+								iohandler_interface $iohandler,
+								container_factory $container,
+								language $language,
+								string $phpbb_root_path,
+								string $php_ext)
 	{
-		parent::__construct(true);
-
-		$this->db				= $container->get('dbal.conn');
 		$this->install_config	= $install_config;
 		$this->io_handler		= $iohandler;
 		$this->language			= $language;
 		$this->phpbb_root_path	= $phpbb_root_path;
 		$this->php_ext			= $php_ext;
+
+		$this->bots_table	= $container->get_parameter('tables.bots');
+		$this->groups_table	= $container->get_parameter('tables.groups');
+
+		parent::__construct(
+			self::get_doctrine_connection($db_helper, $install_config),
+			$this->io_handler,
+			true
+		);
 	}
 
 	/**
@@ -167,89 +201,84 @@ class add_bots extends \phpbb\install\task_base
 	 */
 	public function run()
 	{
-		$this->db->sql_return_on_error(true);
+		$this->group_id = $this->install_config->get('bots_group_id');
+		if ($this->group_id === false)
+		{
+			$sql = 'SELECT group_id FROM ' . $this->groups_table . " WHERE group_name = 'BOTS'";
+			$result = $this->query($sql);
 
-		$sql = 'SELECT group_id
-			FROM ' . GROUPS_TABLE . "
-			WHERE group_name = 'BOTS'";
-		$result = $this->db->sql_query($sql);
-		$group_id = (int) $this->db->sql_fetchfield('group_id');
-		$this->db->sql_freeresult($result);
+			try
+			{
+				$this->group_id = (int) $result->fetchOne();
+				$result->free();
+			}
+			catch (Exception $e)
+			{
+				$this->group_id = 0;
+			}
 
-		if (!$group_id)
+			$this->install_config->set('bots_group_id', $this->group_id);
+		}
+
+		if (!$this->group_id)
 		{
 			// If we reach this point then something has gone very wrong
 			$this->io_handler->add_error_message('NO_GROUP');
 		}
 
-		$i = $this->install_config->get('add_bot_index', 0);
-		$bot_list = array_slice($this->bot_list, $i);
-
-		foreach ($bot_list as $bot_name => $bot_ary)
-		{
-			$user_row = array(
-				'user_type'				=> USER_IGNORE,
-				'group_id'				=> $group_id,
-				'username'				=> $bot_name,
-				'user_regdate'			=> time(),
-				'user_password'			=> '',
-				'user_colour'			=> '9E8DA7',
-				'user_email'			=> '',
-				'user_lang'				=> $this->install_config->get('default_lang'),
-				'user_style'			=> 1,
-				'user_timezone'			=> 'UTC',
-				'user_dateformat'		=> $this->language->lang('default_dateformat'),
-				'user_allow_massemail'	=> 0,
-				'user_allow_pm'			=> 0,
-			);
-
-			if (!function_exists('user_add'))
-			{
-				include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
-			}
-
-			$user_id = user_add($user_row);
-
-			if (!$user_id)
-			{
-				// If we can't insert this user then continue to the next one to avoid inconsistent data
-				$this->io_handler->add_error_message('CONV_ERROR_INSERT_BOT');
-
-				$i++;
-				continue;
-			}
-
-			$sql = 'INSERT INTO ' . BOTS_TABLE . ' ' . $this->db->sql_build_array('INSERT', array(
-				'bot_active'	=> 1,
-				'bot_name'		=> (string) $bot_name,
-				'user_id'		=> (int) $user_id,
-				'bot_agent'		=> (string) $bot_ary[0],
-				'bot_ip'		=> (string) $bot_ary[1],
-			));
-
-			$this->db->sql_query($sql);
-
-			$i++;
-
-			// Stop execution if resource limit is reached
-			if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
-			{
-				break;
-			}
-		}
-
-		$this->install_config->set('add_bot_index', $i);
-
-		if ($i < count($this->bot_list))
-		{
-			throw new resource_limit_reached_exception();
-		}
+		$sql = 'INSERT INTO ' . $this->bots_table . ' '
+			. '(bot_active, bot_name, user_id, bot_agent, bot_ip) VALUES '
+			. '(:bot_active, :bot_name, :user_id, :bot_agent, :bot_ip)';
+		$this->stmt = $this->create_prepared_stmt($sql);
+		$this->execute($this->install_config, $this->bot_list);
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	protected function execute_step($key, $value) : void
+	{
+		if (!function_exists('user_add'))
+		{
+			include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext);
+		}
+
+		$user_id = user_add([
+			'user_type'				=> USER_IGNORE,
+			'group_id'				=> $this->group_id,
+			'username'				=> $key,
+			'user_regdate'			=> time(),
+			'user_password'			=> '',
+			'user_colour'			=> '9E8DA7',
+			'user_email'			=> '',
+			'user_lang'				=> $this->install_config->get('default_lang'),
+			'user_style'			=> 1,
+			'user_timezone'			=> 'UTC',
+			'user_dateformat'		=> $this->language->lang('default_dateformat'),
+			'user_allow_massemail'	=> 0,
+			'user_allow_pm'			=> 0,
+		]);
+
+		if (!$user_id)
+		{
+			// If we can't insert this user then continue to the next one to avoid inconsistent data
+			$this->io_handler->add_error_message('CONV_ERROR_INSERT_BOT');
+			return;
+		}
+
+		$this->exec_prepared_stmt($this->stmt, [
+			'bot_active'	=> 1,
+			'bot_name'		=> (string) $key,
+			'user_id'		=> (int) $user_id,
+			'bot_agent'		=> (string) $value[0],
+			'bot_ip'		=> (string) $value[1],
+		]);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -257,7 +286,7 @@ class add_bots extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_ADD_BOTS';
 	}
diff --git a/phpBB/phpbb/install/module/install_data/task/add_languages.php b/phpBB/phpbb/install/module/install_data/task/add_languages.php
index cf661fb5d4..9f22b4af77 100644
--- a/phpBB/phpbb/install/module/install_data/task/add_languages.php
+++ b/phpBB/phpbb/install/module/install_data/task/add_languages.php
@@ -13,39 +13,66 @@
 
 namespace phpbb\install\module\install_data\task;
 
-class add_languages extends \phpbb\install\task_base
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Doctrine\DBAL\Statement;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
+use phpbb\language\language_file_helper;
+
+class add_languages extends database_task
 {
-	/**
-	 * @var \phpbb\db\driver\driver_interface
-	 */
-	protected $db;
+	use sequential_task;
 
 	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
+	 * @var config
+	 */
+	protected $config;
+
+	/**
+	 * @var iohandler_interface
 	 */
 	protected $iohandler;
 
 	/**
-	 * @var \phpbb\language\language_file_helper
+	 * @var language_file_helper
 	 */
 	protected $language_helper;
 
+	/**
+	 * @var string
+	 */
+	protected $lang_table;
+
+	/**
+	 * @var DriverStatement|Statement
+	 */
+	protected $stmt;
+
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler			Installer's input-output handler
-	 * @param \phpbb\install\helper\container_factory				$container			Installer's DI container
-	 * @param \phpbb\language\language_file_helper					$language_helper	Language file helper service
+	 * @param config					$config				Installer config.
+	 * @param database					$db_helper			Database helper.
+	 * @param iohandler_interface		$iohandler			Installer's input-output handler
+	 * @param container_factory			$container			Installer's DI container
+	 * @param language_file_helper		$language_helper	Language file helper service
 	 */
-	public function __construct(\phpbb\install\helper\iohandler\iohandler_interface $iohandler,
-								\phpbb\install\helper\container_factory $container,
-								\phpbb\language\language_file_helper $language_helper)
+	public function __construct(config $config,
+								database $db_helper,
+								iohandler_interface $iohandler,
+								container_factory $container,
+								language_file_helper $language_helper)
 	{
-		$this->db				= $container->get('dbal.conn');
+		$this->config			= $config;
 		$this->iohandler		= $iohandler;
 		$this->language_helper	= $language_helper;
+		$this->lang_table		= $container->get_parameter('tables.lang');
 
-		parent::__construct(true);
+		parent::__construct(self::get_doctrine_connection($db_helper, $config), $this->iohandler,true);
 	}
 
 	/**
@@ -53,60 +80,36 @@ class add_languages extends \phpbb\install\task_base
 	 */
 	public function run()
 	{
-		$this->db->sql_return_on_error(true);
-
 		$languages = $this->language_helper->get_available_languages();
-		$installed_languages = array();
-
-		foreach ($languages as $lang_info)
-		{
-			$lang_pack = array(
-				'lang_iso'			=> $lang_info['iso'],
-				'lang_dir'			=> $lang_info['iso'],
-				'lang_english_name'	=> htmlspecialchars($lang_info['name'], ENT_COMPAT),
-				'lang_local_name'	=> htmlspecialchars($lang_info['local_name'], ENT_COMPAT, 'UTF-8'),
-				'lang_author'		=> htmlspecialchars($lang_info['author'], ENT_COMPAT, 'UTF-8'),
-			);
-
-			$this->db->sql_query('INSERT INTO ' . LANG_TABLE . ' ' . $this->db->sql_build_array('INSERT', $lang_pack));
-
-			$installed_languages[] = (int) $this->db->sql_nextid();
-			if ($this->db->get_sql_error_triggered())
-			{
-				$error = $this->db->sql_error($this->db->get_sql_error_sql());
-				$this->iohandler->add_error_message($error['message']);
-			}
-		}
-
-		$sql = 'SELECT * FROM ' . PROFILE_FIELDS_TABLE;
-		$result = $this->db->sql_query($sql);
-
-		$insert_buffer = new \phpbb\db\sql_insert_buffer($this->db, PROFILE_LANG_TABLE);
-		while ($row = $this->db->sql_fetchrow($result))
-		{
-			foreach ($installed_languages as $lang_id)
-			{
-				$insert_buffer->insert(array(
-					'field_id'				=> $row['field_id'],
-					'lang_id'				=> $lang_id,
-
-					// Remove phpbb_ from field name
-					'lang_name'				=> strtoupper(substr($row['field_name'], 6)),
-					'lang_explain'			=> '',
-					'lang_default_value'	=> '',
-				));
-			}
-		}
-
-		$this->db->sql_freeresult($result);
-
-		$insert_buffer->flush();
+		$sql = 'INSERT INTO ' . $this->lang_table
+			. ' (lang_iso, lang_dir, lang_english_name, lang_local_name, lang_author)'
+			. ' VALUES (:lang_iso, :lang_dir, :lang_english_name, :lang_local_name, :lang_author)';
+		$this->stmt = $this->create_prepared_stmt($sql);
+		$this->execute($this->config, $languages);
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	protected function execute_step($key, $value) : void
+	{
+		$this->exec_prepared_stmt($this->stmt, [
+			'lang_iso'			=> $value['iso'],
+			'lang_dir'			=> $value['iso'],
+			'lang_english_name'	=> htmlspecialchars($value['name'], ENT_COMPAT),
+			'lang_local_name'	=> htmlspecialchars($value['local_name'], ENT_COMPAT, 'UTF-8'),
+			'lang_author'		=> htmlspecialchars($value['author'], ENT_COMPAT, 'UTF-8'),
+		]);
+
+		$installed_languages = $this->config->get('installed_languages', []);
+		array_push($installed_languages, (int) $this->get_last_insert_id());
+		$this->config->set('installed_languages', $installed_languages);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -114,7 +117,7 @@ class add_languages extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_ADD_LANGUAGES';
 	}
diff --git a/phpBB/phpbb/install/module/install_data/task/add_modules.php b/phpBB/phpbb/install/module/install_data/task/add_modules.php
index c010ab2000..88905a1d2e 100644
--- a/phpBB/phpbb/install/module/install_data/task/add_modules.php
+++ b/phpBB/phpbb/install/module/install_data/task/add_modules.php
@@ -141,7 +141,7 @@ class add_modules extends \phpbb\install\task_base
 	/**
 	 * Constructor
 	 *
-	 * @parma config				$config		Installer's config
+	 * @param config				$config		Installer's config
 	 * @param iohandler_interface	$iohandler	Installer's input-output handler
 	 * @param container_factory		$container	Installer's DI container
 	 */
diff --git a/phpBB/phpbb/install/module/install_data/task/create_search_index.php b/phpBB/phpbb/install/module/install_data/task/create_search_index.php
index ecd0bb40a3..864b729ae5 100644
--- a/phpBB/phpbb/install/module/install_data/task/create_search_index.php
+++ b/phpBB/phpbb/install/module/install_data/task/create_search_index.php
@@ -13,31 +13,53 @@
 
 namespace phpbb\install\module\install_data\task;
 
+use Doctrine\DBAL\Exception;
 use phpbb\auth\auth;
 use phpbb\db\driver\driver_interface;
 use phpbb\event\dispatcher;
-use phpbb\config\config;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
 use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
 use phpbb\search\fulltext_native;
 use phpbb\user;
 
-class create_search_index extends \phpbb\install\task_base
+class create_search_index extends database_task
 {
+	use sequential_task;
+
 	/**
 	 * @var auth
 	 */
 	protected $auth;
 
 	/**
-	 * @var config
+	 * @var \phpbb\config\config
 	 */
 	protected $config;
 
+	/**
+	 * @var \Doctrine\DBAL\Connection
+	 */
+	protected $conn;
+
 	/**
 	 * @var driver_interface
 	 */
 	protected $db;
 
+	/**
+	 * @var config
+	 */
+	protected $installer_config;
+
+	/**
+	 * @var iohandler_interface
+	 */
+	protected $iohandler;
+
 	/**
 	 * @var dispatcher
 	 */
@@ -48,6 +70,11 @@ class create_search_index extends \phpbb\install\task_base
 	 */
 	protected $user;
 
+	/**
+	 * @var fulltext_native
+	 */
+	protected $search_indexer;
+
 	/**
 	 * @var string phpBB root path
 	 */
@@ -58,26 +85,59 @@ class create_search_index extends \phpbb\install\task_base
 	 */
 	protected $php_ext;
 
+	/**
+	 * @var string
+	 */
+	protected $posts_table;
+
+	/**
+	 * @var mixed
+	 */
+	protected $error;
+
 	/**
 	 * Constructor
 	 *
-	 * @param config				$config				phpBB config
+	 * @param config				$config				Installer config.
+	 * @param database				$db_helper			Database helper.
 	 * @param container_factory		$container			Installer's DI container
+	 * @param iohandler_interface	$iohandler			IO manager.
 	 * @param string				$phpbb_root_path	phpBB root path
 	 * @param string				$php_ext			PHP file extension
 	 */
-	public function __construct(config $config, container_factory $container,
-								$phpbb_root_path, $php_ext)
+	public function __construct(
+		config $config,
+		database $db_helper,
+		container_factory $container,
+		iohandler_interface $iohandler,
+		string $phpbb_root_path,
+		string $php_ext)
 	{
+		$this->conn = self::get_doctrine_connection($db_helper, $config);
+
 		$this->auth				= $container->get('auth');
-		$this->config			= $config;
+		$this->config			= $container->get('config');
 		$this->db				= $container->get('dbal.conn');
+		$this->iohandler		= $iohandler;
+		$this->installer_config	= $config;
 		$this->phpbb_dispatcher = $container->get('dispatcher');
 		$this->user 			= $container->get('user');
 		$this->phpbb_root_path	= $phpbb_root_path;
 		$this->php_ext			= $php_ext;
 
-		parent::__construct(true);
+		$this->error = false;
+		$this->search_indexer = new fulltext_native(
+			$this->error,
+			$this->phpbb_root_path,
+			$this->php_ext,
+			$this->auth,
+			$this->config,
+			$this->db,
+			$this->user,
+			$this->phpbb_dispatcher
+		);
+
+		parent::__construct($this->conn, $iohandler, true);
 	}
 
 	/**
@@ -88,33 +148,39 @@ class create_search_index extends \phpbb\install\task_base
 		// Make sure fulltext native load update is set
 		$this->config->set('fulltext_native_load_upd', 1);
 
-		$error = false;
-		$search = new fulltext_native(
-			$error,
-			$this->phpbb_root_path,
-			$this->php_ext,
-			$this->auth,
-			$this->config,
-			$this->db,
-			$this->user,
-			$this->phpbb_dispatcher
-		);
-
-		$sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id
-			FROM ' . POSTS_TABLE;
-		$result = $this->db->sql_query($sql);
-
-		while ($row = $this->db->sql_fetchrow($result))
+		try
 		{
-			$search->index('post', $row['post_id'], $row['post_text'], $row['post_subject'], $row['poster_id'], $row['forum_id']);
+			$sql = 'SELECT post_id, post_subject, post_text, poster_id, forum_id FROM ' . $this->posts_table;
+			$rows = $this->conn->fetchAllAssociative($sql);
 		}
-		$this->db->sql_freeresult($result);
+		catch (Exception $e)
+		{
+			$this->iohandler->add_error_message('INST_ERR_DB', $e->getMessage());
+			$rows = [];
+		}
+
+		$this->execute($this->installer_config, $rows);
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	protected function execute_step($key, $value) : void
+	{
+		$this->search_indexer->index(
+			'post',
+			$value['post_id'],
+			$value['post_text'],
+			$value['post_subject'],
+			$value['poster_id'],
+			$value['forum_id']
+		);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -122,7 +188,7 @@ class create_search_index extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_CREATE_SEARCH_INDEX';
 	}
diff --git a/phpBB/phpbb/install/module/install_data/task/setup_languages.php b/phpBB/phpbb/install/module/install_data/task/setup_languages.php
new file mode 100644
index 0000000000..987ed97e78
--- /dev/null
+++ b/phpBB/phpbb/install/module/install_data/task/setup_languages.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\install\module\install_data\task;
+
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Doctrine\DBAL\Exception;
+use Doctrine\DBAL\Statement;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
+
+class setup_languages extends database_task
+{
+	use sequential_task;
+
+	/**
+	 * @var config
+	 */
+	protected $config;
+
+	/**
+	 * @var Connection
+	 */
+	protected $db;
+
+	/**
+	 * @var iohandler_interface
+	 */
+	protected $iohandler;
+
+	/**
+	 * @var DriverStatement|Statement
+	 */
+	protected $stmt;
+
+	/**
+	 * @var array
+	 */
+	protected $installed_languages;
+
+	/**
+	 * @var string
+	 */
+	protected $profile_fields_table;
+
+	/**
+	 * @var string
+	 */
+	protected $profile_lang_table;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param config				$config
+	 * @param database				$db_helper
+	 * @param iohandler_interface	$io
+	 * @param container_factory		$container
+	 */
+	public function __construct(config $config,
+								database $db_helper,
+								iohandler_interface $io,
+								container_factory $container)
+	{
+		$this->config		= $config;
+		$this->db			= self::get_doctrine_connection($db_helper, $config);
+		$this->iohandler	= $io;
+
+		$this->profile_fields_table	= $container->get_parameter('tables.profile_fields');
+		$this->profile_lang_table	= $container->get_parameter('tables.profile_fields_language');
+
+		parent::__construct($this->db, $io, true);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	public function run()
+	{
+		$this->installed_languages = $this->config->get('installed_languages', []);
+		$profile_fields = $this->config->get('profile_field_rows', false);
+		if ($profile_fields === false)
+		{
+			try
+			{
+				$rows = $this->db->fetchAllAssociative('SELECT * FROM ' . $this->profile_fields_table);
+			}
+			catch (Exception $e)
+			{
+				$this->iohandler->add_error_message('INST_ERR_DB', $e->getMessage());
+				$rows = [];
+			}
+
+			$this->config->set('profile_field_rows', $rows);
+			$profile_fields = $rows;
+		}
+
+		$sql = 'INSERT INTO ' . $this->profile_lang_table
+			. ' (field_id, lang_id, lang_name, lang_explain, lang_default_value)'
+			. " VALUES (:field_id, :lang_id, :lang_name, '', '')";
+		$this->stmt = $this->create_prepared_stmt($sql);
+		$this->execute($this->config, $profile_fields);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function execute_step($key, $value) : void
+	{
+		foreach ($this->installed_languages as $lang_id)
+		{
+			$this->exec_prepared_stmt($this->stmt, [
+				'field_id'	=> $value['field_id'],
+				'lang_id'	=> $lang_id,
+
+				// Remove phpbb_ from field name
+				'lang_name' => strtoupper(substr($value['field_name'], 6)),
+			]);
+		}
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
+	{
+		return 1;
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	public function get_task_lang_name() : string
+	{
+		return 'TASK_SET_LANGUAGES';
+	}
+}
diff --git a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
index 91d7884aa4..190ad8c907 100644
--- a/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
+++ b/phpBB/phpbb/install/module/install_database/task/add_config_settings.php
@@ -13,43 +13,49 @@
 
 namespace phpbb\install\module\install_database\task;
 
-use phpbb\install\exception\resource_limit_reached_exception;
+use Doctrine\DBAL\Driver\Statement as DriverStatement;
+use Doctrine\DBAL\Statement;
+use phpbb\filesystem\filesystem_interface;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
+use phpbb\language\language;
 
 /**
  * Create database schema
  */
-class add_config_settings extends \phpbb\install\task_base
+class add_config_settings extends database_task
 {
+	use sequential_task;
+
 	/**
 	 * @var \phpbb\db\driver\driver_interface
 	 */
 	protected $db;
 
 	/**
-	 * @var \phpbb\filesystem\filesystem_interface
+	 * @var filesystem_interface
 	 */
 	protected $filesystem;
 
 	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $install_config;
 
 	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
+	 * @var iohandler_interface
 	 */
 	protected $iohandler;
 
 	/**
-	 * @var \phpbb\language\language
+	 * @var language
 	 */
 	protected $language;
 
-	/**
-	 * @var \phpbb\passwords\manager
-	 */
-	protected $password_manager;
-
 	/**
 	 * @var string
 	 */
@@ -61,64 +67,44 @@ class add_config_settings extends \phpbb\install\task_base
 	protected $config_table;
 
 	/**
-	 * @var string
+	 * @var Statement|DriverStatement
 	 */
-	protected $user_table;
-
-	/**
-	 * @var string
-	 */
-	protected $topics_table;
-
-	/**
-	 * @var string
-	 */
-	protected $forums_table;
-
-	/**
-	 * @var string
-	 */
-	protected $posts_table;
-
-	/**
-	 * @var string
-	 */
-	protected $moderator_cache_table;
+	protected $stmt;
 
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\filesystem\filesystem_interface				$filesystem			Filesystem service
-	 * @param \phpbb\install\helper\config							$install_config		Installer's config helper
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler			Installer's input-output handler
-	 * @param \phpbb\install\helper\container_factory				$container			Installer's DI container
-	 * @param \phpbb\language\language								$language			Language service
-	 * @param string												$phpbb_root_path	Path to phpBB's root
+	 * @param database				$db_helper			Database helper
+	 * @param filesystem_interface	$filesystem			Filesystem service
+	 * @param config				$install_config		Installer's config helper
+	 * @param iohandler_interface	$iohandler			Installer's input-output handler
+	 * @param container_factory		$container			Installer's DI container
+	 * @param language				$language			Language service
+	 * @param string				$phpbb_root_path	Path to phpBB's root
 	 */
-	public function __construct(\phpbb\filesystem\filesystem_interface $filesystem,
-								\phpbb\install\helper\config $install_config,
-								\phpbb\install\helper\iohandler\iohandler_interface $iohandler,
-								\phpbb\install\helper\container_factory $container,
-								\phpbb\language\language $language,
-								$phpbb_root_path)
+	public function __construct(database $db_helper,
+								filesystem_interface $filesystem,
+								config $install_config,
+								iohandler_interface $iohandler,
+								container_factory $container,
+								language $language,
+								string $phpbb_root_path)
 	{
 		$this->db				= $container->get('dbal.conn');
 		$this->filesystem		= $filesystem;
 		$this->install_config	= $install_config;
 		$this->iohandler		= $iohandler;
 		$this->language			= $language;
-		$this->password_manager	= $container->get('passwords.manager');
 		$this->phpbb_root_path	= $phpbb_root_path;
 
 		// Table names
-		$this->config_table				= $container->get_parameter('tables.config');
-		$this->forums_table				= $container->get_parameter('tables.forums');
-		$this->topics_table				= $container->get_parameter('tables.topics');
-		$this->user_table				= $container->get_parameter('tables.users');
-		$this->moderator_cache_table	= $container->get_parameter('tables.moderator_cache');
-		$this->posts_table				= $container->get_parameter('tables.posts');
+		$this->config_table = $container->get_parameter('tables.config');
 
-		parent::__construct(true);
+		parent::__construct(
+			self::get_doctrine_connection($db_helper, $install_config),
+			$this->iohandler,
+			true
+		);
 	}
 
 	/**
@@ -126,12 +112,14 @@ class add_config_settings extends \phpbb\install\task_base
 	 */
 	public function run()
 	{
-		$this->db->sql_return_on_error(true);
+		$current_time = $this->install_config->get('install_board_time');
+		if ($current_time === false)
+		{
+			$current_time = time();
+			$this->install_config->set('install_board_time', $current_time);
+		}
 
 		$server_name	= $this->install_config->get('server_name');
-		$current_time 	= time();
-		$user_ip		= phpbb_ip_normalise($this->iohandler->get_server_variable('REMOTE_ADDR'));
-		$user_ip		= ($user_ip === false) ? '' : $user_ip;
 		$referer		= $this->iohandler->get_server_variable('REFERER');
 
 		// Calculate cookie domain
@@ -142,160 +130,52 @@ class add_config_settings extends \phpbb\install\task_base
 			$cookie_domain = substr($cookie_domain, 3);
 		}
 
-		// Set default config and post data, this applies to all DB's
-		$sql_ary = array(
-			'INSERT INTO ' . $this->config_table . " (config_name, config_value)
-				VALUES ('board_startdate', '$current_time')",
+		$updates = [
+			'board_startdate' => (string) $current_time,
+			'default_lang' => $this->install_config->get('default_lang'),
 
-			'INSERT INTO ' . $this->config_table . " (config_name, config_value)
-				VALUES ('default_lang', '" . $this->db->sql_escape($this->install_config->get('default_lang')) . "')",
+			'server_name' => $this->install_config->get('server_name'),
+			'server_port' => $this->install_config->get('server_port'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('server_name')) . "'
-				WHERE config_name = 'server_name'",
+			'board_email' => $this->install_config->get('board_email'),
+			'board_contact' => $this->install_config->get('board_email'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('server_port')) . "'
-				WHERE config_name = 'server_port'",
+			'cookie_domain' => $cookie_domain,
+			'cookie_secure' => $this->install_config->get('cookie_secure'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('board_email')) . "'
-				WHERE config_name = 'board_email'",
+			'default_dateformat' => $this->language->lang('default_dateformat'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('board_email')) . "'
-				WHERE config_name = 'board_contact'",
+			'email_enable'		=> $this->install_config->get('email_enable'),
+			'smtp_delivery'		=> $this->install_config->get('smtp_delivery'),
+			'smtp_host'			=> $this->install_config->get('smtp_host'),
+			'smtp_port'			=> $this->install_config->get('smtp_port'),
+			'smtp_auth_method'	=> $this->install_config->get('smtp_auth'),
+			'smtp_username'		=> $this->install_config->get('smtp_user'),
+			'smtp_password'		=> $this->install_config->get('smtp_pass'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($cookie_domain) . "'
-				WHERE config_name = 'cookie_domain'",
+			'force_server_vars'	=> $this->install_config->get('force_server_vars'),
+			'script_path'		=> $this->install_config->get('script_path'),
+			'server_protocol'	=> $this->install_config->get('server_protocol'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "'
-				WHERE config_name = 'default_dateformat'",
+			'newest_username' => $this->install_config->get('admin_name'),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('email_enable')) . "'
-				WHERE config_name = 'email_enable'",
+			'avatar_salt'	=> md5(mt_rand()),
+			'plupload_salt'	=> md5(mt_rand()),
 
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_delivery')) . "'
-				WHERE config_name = 'smtp_delivery'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_host')) . "'
-				WHERE config_name = 'smtp_host'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_port')) . "'
-				WHERE config_name = 'smtp_port'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_auth')) . "'
-				WHERE config_name = 'smtp_auth_method'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_user')) . "'
-				WHERE config_name = 'smtp_username'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('smtp_pass')) . "'
-				WHERE config_name = 'smtp_password'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('cookie_secure')) . "'
-				WHERE config_name = 'cookie_secure'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('force_server_vars')) . "'
-				WHERE config_name = 'force_server_vars'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('script_path')) . "'
-				WHERE config_name = 'script_path'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('server_protocol')) . "'
-				WHERE config_name = 'server_protocol'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'
-				WHERE config_name = 'newest_username'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . md5(mt_rand()) . "'
-				WHERE config_name = 'avatar_salt'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . md5(mt_rand()) . "'
-				WHERE config_name = 'plupload_salt'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('board_name')) . "'
-				WHERE config_name = 'sitename'",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->install_config->get('board_description')) . "'
-				WHERE config_name = 'site_desc'",
-
-			'UPDATE ' . $this->user_table . "
-				SET username = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "',
-					user_password='" . $this->password_manager->hash($this->install_config->get('admin_passwd')) . "',
-					user_ip = '" . $this->db->sql_escape($user_ip) . "',
-					user_lang = '" . $this->db->sql_escape($this->install_config->get('user_language', 'en')) . "',
-					user_email='" . $this->db->sql_escape($this->install_config->get('board_email')) . "',
-					user_dateformat='" . $this->db->sql_escape($this->language->lang('default_dateformat')) . "',
-					username_clean = '" . $this->db->sql_escape(utf8_clean_string($this->install_config->get('admin_name'))) . "'
-				WHERE username = 'Admin'",
-
-			'UPDATE ' . $this->moderator_cache_table . "
-				SET username = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'
-				WHERE username = 'Admin'",
-
-			'UPDATE ' . $this->forums_table . "
-				SET forum_last_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'
-				WHERE forum_last_poster_name = 'Admin'",
-
-			'UPDATE ' . $this->topics_table . "
-				SET topic_first_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "',
-				topic_last_poster_name = '" . $this->db->sql_escape($this->install_config->get('admin_name')) . "'
-				WHERE topic_first_poster_name = 'Admin'
-					OR topic_last_poster_name = 'Admin'",
-
-			'UPDATE ' . $this->user_table . "
-				SET user_regdate = $current_time",
-
-			'UPDATE ' . $this->posts_table . "
-				SET post_time = $current_time, poster_ip = '" . $this->db->sql_escape($user_ip) . "'",
-
-			'UPDATE ' . $this->topics_table . "
-				SET topic_time = $current_time, topic_last_post_time = $current_time",
-
-			'UPDATE ' . $this->forums_table . "
-				SET forum_last_post_time = $current_time",
-
-			'UPDATE ' . $this->config_table . "
-				SET config_value = '" . $this->db->sql_escape($this->db->sql_server_info(true)) . "'
-				WHERE config_name = 'dbms_version'",
-		);
+			'sitename'	=> $this->install_config->get('board_name'),
+			'site_desc'	=> $this->install_config->get('board_description'),
+		];
 
 		if (@extension_loaded('gd'))
 		{
-			$sql_ary[] = 'UPDATE ' . $this->config_table . "
-				SET config_value = 'core.captcha.plugins.gd'
-				WHERE config_name = 'captcha_plugin'";
-
-			$sql_ary[] = 'UPDATE ' . $this->config_table . "
-				SET config_value = '1'
-				WHERE config_name = 'captcha_gd'";
+			$updates['captcha_plugin'] = 'core.captcha.plugins.gd';
+			$updates['captcha_gd'] = '1';
 		}
 
 		$ref = substr($referer, strpos($referer, '://') + 3);
 		if (!(stripos($ref, $server_name) === 0))
 		{
-			$sql_ary[] = 'UPDATE ' . $this->config_table . "
-				SET config_value = '0'
-				WHERE config_name = 'referer_validation'";
+			$updates['referer_validation'] = '0';
 		}
 
 		// We set a (semi-)unique cookie name to bypass login issues related to the cookie name.
@@ -305,54 +185,40 @@ class add_config_settings extends \phpbb\install\task_base
 		$rand_str = substr($rand_str, 0, 5);
 		$cookie_name .= strtolower($rand_str);
 
-		$sql_ary[] = 'UPDATE ' . $this->config_table . "
-			SET config_value = '" . $this->db->sql_escape($cookie_name) . "'
-			WHERE config_name = 'cookie_name'";
+		$updates['cookie_name'] = $cookie_name;
 
 		// Disable avatars if upload directory is not writable
 		if (!$this->filesystem->is_writable($this->phpbb_root_path . 'images/avatars/upload/'))
 		{
-			$sql_ary[] = 'UPDATE ' . $this->config_table . "
-				SET config_value = '0'
-				WHERE config_name = 'allow_avatar'";
-
-			$sql_ary[] = 'UPDATE ' . $this->config_table . "
-				SET config_value = '0'
-				WHERE config_name = 'allow_avatar_upload'";
+			$updates['allow_avatar'] = '0';
+			$updates['allow_avatar_upload'] = '0';
 		}
 
-		$i = $this->install_config->get('add_config_settings_index', 0);
-		$total = count($sql_ary);
-		$sql_ary = array_slice($sql_ary, $i);
+		$this->stmt = $this->create_prepared_stmt(
+			'UPDATE ' . $this->config_table . ' SET config_value = :value WHERE config_name = :name'
+		);
 
-		foreach ($sql_ary as $sql)
+		if ($this->stmt !== null)
 		{
-			if (!$this->db->sql_query($sql))
-			{
-				$error = $this->db->sql_error($this->db->get_sql_error_sql());
-				$this->iohandler->add_error_message('INST_ERR_DB', $error['message']);
-			}
-
-			$i++;
-
-			// Stop execution if resource limit is reached
-			if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
-			{
-				break;
-			}
-		}
-
-		if ($i < $total)
-		{
-			$this->install_config->set('add_config_settings_index', $i);
-			throw new resource_limit_reached_exception();
+			$this->execute($this->install_config, $updates);
 		}
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	protected function execute_step($key, $value) : void
+	{
+		$this->exec_prepared_stmt($this->stmt, [
+			'name' => $key,
+			'value' => $value,
+		]);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -360,7 +226,7 @@ class add_config_settings extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_ADD_CONFIG_SETTINGS';
 	}
diff --git a/phpBB/phpbb/install/module/install_database/task/add_default_data.php b/phpBB/phpbb/install/module/install_database/task/add_default_data.php
index c05e5321fb..bf64f2276a 100644
--- a/phpBB/phpbb/install/module/install_database/task/add_default_data.php
+++ b/phpBB/phpbb/install/module/install_database/task/add_default_data.php
@@ -13,35 +13,38 @@
 
 namespace phpbb\install\module\install_database\task;
 
-use phpbb\install\exception\resource_limit_reached_exception;
+use Doctrine\DBAL\Connection;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
+use phpbb\language\language;
 
 /**
  * Create database schema
  */
-class add_default_data extends \phpbb\install\task_base
+class add_default_data extends database_task
 {
+	use sequential_task;
+
 	/**
-	 * @var \phpbb\db\driver\driver_interface
+	 * @var Connection
 	 */
 	protected $db;
 
 	/**
-	 * @var \phpbb\install\helper\database
+	 * @var database
 	 */
 	protected $database_helper;
 
 	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $config;
 
 	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
-	 */
-	protected $iohandler;
-
-	/**
-	 * @var \phpbb\language\language
+	 * @var language
 	 */
 	protected $language;
 
@@ -53,28 +56,25 @@ class add_default_data extends \phpbb\install\task_base
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\database						$db_helper	Installer's database helper
-	 * @param \phpbb\install\helper\config							$config		Installer config
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler	Installer's input-output handler
-	 * @param \phpbb\install\helper\container_factory				$container	Installer's DI container
-	 * @param \phpbb\language\language								$language	Language service
-	 * @param string												$root_path	Root path of phpBB
+	 * @param database				$db_helper	Installer's database helper
+	 * @param config				$config		Installer config
+	 * @param iohandler_interface	$iohandler	Installer's input-output handler
+	 * @param language				$language	Language service
+	 * @param string				$root_path	Root path of phpBB
 	 */
-	public function __construct(\phpbb\install\helper\database $db_helper,
-								\phpbb\install\helper\config $config,
-								\phpbb\install\helper\iohandler\iohandler_interface $iohandler,
-								\phpbb\install\helper\container_factory $container,
-								\phpbb\language\language $language,
-								$root_path)
+	public function __construct(database $db_helper,
+								config $config,
+								iohandler_interface $iohandler,
+								language $language,
+								string $root_path)
 	{
-		$this->db				= $container->get('dbal.conn.driver');
+		$this->db				= self::get_doctrine_connection($db_helper, $config);
 		$this->database_helper	= $db_helper;
 		$this->config			= $config;
-		$this->iohandler		= $iohandler;
 		$this->language			= $language;
 		$this->phpbb_root_path	= $root_path;
 
-		parent::__construct(true);
+		parent::__construct($this->db, $iohandler, true);
 	}
 
 	/**
@@ -82,8 +82,6 @@ class add_default_data extends \phpbb\install\task_base
 	 */
 	public function run()
 	{
-		$this->db->sql_return_on_error(true);
-
 		$table_prefix = $this->config->get('table_prefix');
 		$dbms = $this->config->get('dbms');
 		$dbms_info = $this->database_helper->get_available_dbms($dbms);
@@ -98,53 +96,55 @@ class add_default_data extends \phpbb\install\task_base
 		$sql_query = $this->database_helper->remove_comments($sql_query);
 		$sql_query = $this->database_helper->split_sql_file($sql_query, $dbms_info[$dbms]['DELIM']);
 
-		$i = $this->config->get('add_default_data_index', 0);
-		$total = count($sql_query);
-		$sql_query = array_slice($sql_query, $i);
+		$this->execute($this->config, $sql_query);
+	}
 
-		foreach ($sql_query as $sql)
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function execute_step($key, $value) : void
+	{
+		$sql = trim($value);
+		switch ($sql)
 		{
-			if (!$this->db->sql_query($sql))
-			{
-				$error = $this->db->sql_error($this->db->get_sql_error_sql());
-				$this->iohandler->add_error_message('INST_ERR_DB', $error['message']);
-			}
+			case 'BEGIN':
+				$this->db->beginTransaction();
+			break;
 
-			$i++;
+			case 'COMMIT':
+				$this->db->commit();
+			break;
 
-			// Stop execution if resource limit is reached
-			if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0)
-			{
-				break;
-			}
-		}
-
-		$this->config->set('add_default_data_index', $i);
-
-		if ($i < $total)
-		{
-			throw new resource_limit_reached_exception();
+			default:
+				$this->exec_sql($sql);
+			break;
 		}
 	}
 
 	/**
 	 * Process DB specific SQL
 	 *
+	 * @param string $query
+	 *
 	 * @return string
 	 */
-	protected function replace_dbms_specific_sql($query)
+	protected function replace_dbms_specific_sql(string $query) : string
 	{
-		if ($this->db instanceof \phpbb\db\driver\mssql_base)
+		$dbms = $this->config->get('dbms');
+		switch ($dbms)
 		{
-			$query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $query);
-		}
-		else if ($this->db instanceof \phpbb\db\driver\postgres)
-		{
-			$query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $query);
-		}
-		else if ($this->db instanceof \phpbb\db\driver\mysql_base)
-		{
-			$query = str_replace('\\', '\\\\', $query);
+			case 'mssql_odbc':
+			case 'mssqlnative':
+				$query = preg_replace('#\# MSSQL IDENTITY (phpbb_[a-z_]+) (ON|OFF) \##s', 'SET IDENTITY_INSERT \1 \2;', $query);
+			break;
+
+			case 'postgres':
+				$query = preg_replace('#\# POSTGRES (BEGIN|COMMIT) \##s', '\1; ', $query);
+			break;
+
+			case 'mysqli':
+				$query = str_replace('\\', '\\\\', $query);
+			break;
 		}
 
 		return $query;
@@ -156,11 +156,15 @@ class add_default_data extends \phpbb\install\task_base
 	 * @param array	$matches
 	 * @return string
 	 */
-	public function lang_replace_callback($matches)
+	public function lang_replace_callback(array $matches) : string
 	{
 		if (!empty($matches[1]))
 		{
-			return $this->db->sql_escape($this->language->lang($matches[1]));
+			$translation = $this->language->lang($matches[1]);
+
+			// This is might not be secure, but these queries should not be malicious anyway.
+			$quoted = $this->db->quote($translation) ?: '\'' . addcslashes($translation, '\'') . '\'';
+			return substr($quoted, 1, -1);
 		}
 
 		return '';
@@ -169,7 +173,7 @@ class add_default_data extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -177,7 +181,7 @@ class add_default_data extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_ADD_DEFAULT_DATA';
 	}
diff --git a/phpBB/phpbb/install/module/install_database/task/add_tables.php b/phpBB/phpbb/install/module/install_database/task/add_tables.php
index c5ecdaa6cb..82aeb7df8a 100644
--- a/phpBB/phpbb/install/module/install_database/task/add_tables.php
+++ b/phpBB/phpbb/install/module/install_database/task/add_tables.php
@@ -13,25 +13,32 @@
 
 namespace phpbb\install\module\install_database\task;
 
-use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\db\driver\driver_interface;
+use phpbb\db\tools\tools_interface;
+use phpbb\install\helper\config;
+use phpbb\install\helper\database;
+use phpbb\install\sequential_task;
+use phpbb\install\task_base;
 
 /**
  * Create tables
  */
-class add_tables extends \phpbb\install\task_base
+class add_tables extends task_base
 {
+	use sequential_task;
+
 	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $config;
 
 	/**
-	 * @var \phpbb\db\driver\driver_interface
+	 * @var driver_interface
 	 */
 	protected $db;
 
 	/**
-	 * @var \phpbb\db\tools\tools_interface
+	 * @var tools_interface
 	 */
 	protected $db_tools;
 
@@ -40,16 +47,26 @@ class add_tables extends \phpbb\install\task_base
 	 */
 	protected $schema_file_path;
 
+	/**
+	 * @var string
+	 */
+	protected $table_prefix;
+
+	/**
+	 * @var bool
+	 */
+	protected $change_prefix;
+
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\config				$config
-	 * @param \phpbb\install\helper\database			$db_helper
-	 * @param string									$phpbb_root_path
+	 * @param config	$config
+	 * @param database	$db_helper
+	 * @param string	$phpbb_root_path
 	 */
-	public function __construct(\phpbb\install\helper\config $config,
-								\phpbb\install\helper\database $db_helper,
-								$phpbb_root_path)
+	public function __construct(config $config,
+								database $db_helper,
+								string $phpbb_root_path)
 	{
 		$dbms = $db_helper->get_available_dbms($config->get('dbms'));
 		$dbms = $dbms[$config->get('dbms')]['DRIVER'];
@@ -69,6 +86,8 @@ class add_tables extends \phpbb\install\task_base
 		$this->config			= $config;
 		$this->db_tools			= $factory->get($this->db);
 		$this->schema_file_path	= $phpbb_root_path . 'store/schema.json';
+		$this->table_prefix		= $this->config->get('table_prefix');
+		$this->change_prefix	= $this->config->get('change_table_prefix', true);
 
 		parent::__construct(true);
 	}
@@ -80,55 +99,37 @@ class add_tables extends \phpbb\install\task_base
 	{
 		$this->db->sql_return_on_error(true);
 
-		$table_prefix = $this->config->get('table_prefix');
-		$change_prefix = $this->config->get('change_table_prefix', true);
-
 		if (!defined('CONFIG_TABLE'))
 		{
 			// CONFIG_TABLE is required by sql_create_index() to check the
 			// length of index names. However table_prefix is not defined
 			// here yet, so we need to create the constant ourselves.
-			define('CONFIG_TABLE', $table_prefix . 'config');
+			define('CONFIG_TABLE', $this->table_prefix . 'config');
 		}
 
 		$db_table_schema = @file_get_contents($this->schema_file_path);
 		$db_table_schema = json_decode($db_table_schema, true);
-		$total = count($db_table_schema);
-		$i = $this->config->get('add_table_index', 0);
-		$db_table_schema = array_slice($db_table_schema, $i);
 
-		foreach ($db_table_schema as $table_name => $table_data)
-		{
-			$i++;
+		$this->execute($this->config, $db_table_schema);
 
-			$this->db_tools->sql_create_table(
-				( ($change_prefix) ? ($table_prefix . substr($table_name, 6)) : $table_name ),
-				$table_data
-			);
-
-			// Stop execution if resource limit is reached
-			if ($this->config->get_time_remaining() <= 0 || $this->config->get_memory_remaining() <= 0)
-			{
-				break;
-			}
-		}
-
-		$this->config->set('add_table_index', $i);
-
-		if ($i < $total)
-		{
-			throw new resource_limit_reached_exception();
-		}
-		else
-		{
-			@unlink($this->schema_file_path);
-		}
+		@unlink($this->schema_file_path);
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	protected function execute_step($key, $value) : void
+	{
+		$this->db_tools->sql_create_table(
+			($this->change_prefix) ? ($this->table_prefix . substr($key, 6)) : $key,
+			$value
+		);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -136,7 +137,7 @@ class add_tables extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_CREATE_TABLES';
 	}
diff --git a/phpBB/phpbb/install/module/install_database/task/set_up_database.php b/phpBB/phpbb/install/module/install_database/task/set_up_database.php
index 4da5ece228..86af67b7e4 100644
--- a/phpBB/phpbb/install/module/install_database/task/set_up_database.php
+++ b/phpBB/phpbb/install/module/install_database/task/set_up_database.php
@@ -13,36 +13,32 @@
 
 namespace phpbb\install\module\install_database\task;
 
+use phpbb\filesystem\filesystem_interface;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+
 /**
  * Set up database for table generation
  */
-class set_up_database extends \phpbb\install\task_base
+class set_up_database extends database_task
 {
 	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $config;
 
 	/**
-	 * @var \phpbb\db\driver\driver_interface
-	 */
-	protected $db;
-
-	/**
-	 * @var \phpbb\install\helper\database
+	 * @var database
 	 */
 	protected $database_helper;
 
 	/**
-	 * @var \phpbb\filesystem\filesystem_interface
+	 * @var filesystem_interface
 	 */
 	protected $filesystem;
 
-	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
-	 */
-	protected $iohandler;
-
 	/**
 	 * @var string
 	 */
@@ -56,45 +52,34 @@ class set_up_database extends \phpbb\install\task_base
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\config							$config
-	 * @param \phpbb\install\helper\database						$db_helper
-	 * @param \phpbb\filesystem\filesystem_interface				$filesystem
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler
-	 * @param string												$phpbb_root_path
+	 * @param config				$config
+	 * @param database				$db_helper
+	 * @param filesystem_interface	$filesystem
+	 * @param iohandler_interface	$iohandler
+	 * @param string				$phpbb_root_path
 	 */
-	public function __construct(\phpbb\install\helper\config $config,
-								\phpbb\install\helper\database $db_helper,
-								\phpbb\filesystem\filesystem_interface $filesystem,
-								\phpbb\install\helper\iohandler\iohandler_interface $iohandler,
-								$phpbb_root_path)
+	public function __construct(config $config,
+								database $db_helper,
+								filesystem_interface $filesystem,
+								iohandler_interface $iohandler,
+								string $phpbb_root_path)
 	{
-		$dbms = $db_helper->get_available_dbms($config->get('dbms'));
-		$dbms = $dbms[$config->get('dbms')]['DRIVER'];
-
-		$this->db				= new $dbms();
-		$this->db->sql_connect(
-			$config->get('dbhost'),
-			$config->get('dbuser'),
-			$config->get('dbpasswd'),
-			$config->get('dbname'),
-			$config->get('dbport'),
-			false,
-			false
-		);
-
 		$this->config			= $config;
 		$this->database_helper	= $db_helper;
 		$this->filesystem		= $filesystem;
-		$this->iohandler		= $iohandler;
 		$this->phpbb_root_path	= $phpbb_root_path;
 
-		parent::__construct(false);
+		parent::__construct(
+			self::get_doctrine_connection($db_helper, $config),
+			$iohandler,
+			false
+		);
 	}
 
 	/**
 	 * {@inheritdoc}
 	 */
-	public function check_requirements()
+	public function check_requirements() : bool
 	{
 		$dbms = $this->config->get('dbms');
 		$dbms_info = $this->database_helper->get_available_dbms($dbms);
@@ -115,25 +100,19 @@ class set_up_database extends \phpbb\install\task_base
 	 */
 	public function run()
 	{
-		$this->db->sql_return_on_error(true);
-
 		$dbms = $this->config->get('dbms');
 		$dbms_info = $this->database_helper->get_available_dbms($dbms);
 		$delimiter = $dbms_info[$dbms]['DELIM'];
 		$table_prefix = $this->config->get('table_prefix');
 
 		$sql_query = @file_get_contents($this->schema_file_path);
-		$sql_query = preg_replace('#phpbb_#i', $table_prefix, $sql_query);
+		$sql_query = str_replace('phpbb_', ' ' . $table_prefix, $sql_query);
 		$sql_query = $this->database_helper->remove_comments($sql_query);
 		$sql_query = $this->database_helper->split_sql_file($sql_query, $delimiter);
 
 		foreach ($sql_query as $sql)
 		{
-			if (!$this->db->sql_query($sql))
-			{
-				$error = $this->db->sql_error($this->db->get_sql_error_sql());
-				$this->iohandler->add_error_message('INST_ERR_DB', $error['message']);
-			}
+			$this->exec_sql($sql);
 		}
 
 		unset($sql_query);
@@ -142,7 +121,7 @@ class set_up_database extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	static public function get_step_count()
+	static public function get_step_count() : int
 	{
 		return 1;
 	}
@@ -150,7 +129,7 @@ class set_up_database extends \phpbb\install\task_base
 	/**
 	 * {@inheritdoc}
 	 */
-	public function get_task_lang_name()
+	public function get_task_lang_name() : string
 	{
 		return 'TASK_SETUP_DATABASE';
 	}
diff --git a/phpBB/phpbb/install/module/install_database/task/update_user_and_post_data.php b/phpBB/phpbb/install/module/install_database/task/update_user_and_post_data.php
new file mode 100644
index 0000000000..457ce4cd27
--- /dev/null
+++ b/phpBB/phpbb/install/module/install_database/task/update_user_and_post_data.php
@@ -0,0 +1,186 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\install\module\install_database\task;
+
+use phpbb\install\database_task;
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\language\language;
+
+/**
+ * Update the admin's info as well as the welcome post.
+ */
+class update_user_and_post_data extends database_task
+{
+	/** @var config */
+	private $install_config;
+
+	private $iohandler;
+
+	/** @var language */
+	private $language;
+
+	/** @var \phpbb\passwords\manager */
+	private $password_manager;
+
+	/** @var string */
+	private $forums_table;
+
+	/** @var string */
+	private $moderator_cache_table;
+
+	/** @var string */
+	private $posts_table;
+
+	/** @var string */
+	private $topics_table;
+
+	/** @var string */
+	private $user_table;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param config				$install_config
+	 * @param container_factory		$container
+	 * @param database				$db_helper
+	 * @param iohandler_interface	$iohandler
+	 * @param language				$language
+	 */
+	public function __construct(
+		config $install_config,
+		container_factory $container,
+		database $db_helper,
+		iohandler_interface $iohandler,
+		language $language)
+	{
+		$this->install_config	= $install_config;
+		$this->iohandler		= $iohandler;
+		$this->language			= $language;
+		$this->password_manager	= $container->get('passwords.manager');
+
+		$this->forums_table				= $container->get_parameter('tables.forums');
+		$this->moderator_cache_table	= $container->get_parameter('tables.moderator_cache');
+		$this->posts_table				= $container->get_parameter('tables.posts');
+		$this->topics_table				= $container->get_parameter('tables.topics');
+		$this->user_table				= $container->get_parameter('tables.users');
+
+		parent::__construct(
+			self::get_doctrine_connection($db_helper, $install_config),
+			$this->iohandler,
+			true
+		);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	public function run()
+	{
+		// Force a refresh.
+		$count = $this->install_config->get('correct_user_and_post_data_count');
+		if ($count === false)
+		{
+			if ($this->install_config->get_time_remaining() < 5)
+			{
+				$this->install_config->set('correct_user_and_post_data_count', 1);
+				throw new resource_limit_reached_exception();
+			}
+		}
+
+		$user_ip = phpbb_ip_normalise($this->iohandler->get_server_variable('REMOTE_ADDR'));
+		$user_ip = ($user_ip === false) ? '' : $user_ip;
+		$current_time = $this->install_config->get('install_board_time', time());
+
+		// Update user data
+		$sql = 'UPDATE ' . $this->user_table
+			. ' SET username = :username,'
+			. '		user_password = :password,'
+			. '		user_ip = :ip,'
+			. '		user_lang = :lang,'
+			. '		user_email = :email,'
+			. '		user_dateformat = :dateformat,'
+			. '		username_clean = :clean_username'
+			. ' WHERE username = \'Admin\'';
+
+		$this->create_and_execute_prepared_stmt($sql, [
+			'username'			=> $this->install_config->get('admin_name'),
+			'password'			=> $this->password_manager->hash($this->install_config->get('admin_passwd')),
+			'ip'				=> $user_ip,
+			'lang'				=> $this->install_config->get('user_language', 'en'),
+			'email'				=> $this->install_config->get('board_email'),
+			'dateformat'		=> $this->language->lang('default_dateformat'),
+			'clean_username'	=> utf8_clean_string($this->install_config->get('admin_name')),
+		]);
+		$this->exec_sql('UPDATE ' . $this->user_table . ' SET user_regdate = ' . $current_time);
+
+		// Update forums table
+		$sql = 'UPDATE ' . $this->forums_table
+			. ' SET forum_last_poster_name = :poster_name'
+			. ' WHERE forum_last_poster_name = \'Admin\'';
+		$this->create_and_execute_prepared_stmt($sql, [
+			'poster_name' => $this->install_config->get('admin_name'),
+		]);
+		$this->exec_sql('UPDATE ' . $this->forums_table . ' SET forum_last_post_time = ' . $current_time);
+
+		// Topics table
+		$sql = 'UPDATE ' . $this->topics_table
+			. '	SET topic_first_poster_name = :poster_name,'
+			. '		topic_last_poster_name = :poster_name'
+			. ' WHERE topic_first_poster_name = \'Admin\''
+			. '	OR topic_last_poster_name = \'Admin\'';
+		$this->create_and_execute_prepared_stmt($sql, [
+			'poster_name' => $this->install_config->get('admin_name'),
+		]);
+		$this->exec_sql('UPDATE ' . $this->topics_table
+			. ' SET topic_time = ' . $current_time . ', topic_last_post_time = ' . $current_time
+		);
+
+		// Posts table
+		$sql = 'UPDATE ' . $this->posts_table
+			. ' SET post_time = :post_time,'
+			. '		poster_ip = :poster_ip';
+		$this->create_and_execute_prepared_stmt($sql, [
+			'post_time' => $current_time,
+			'poster_ip' => $user_ip,
+		]);
+
+		// Moderator cache
+		$sql = 'UPDATE ' . $this->moderator_cache_table
+			. ' SET username = :username'
+			. ' WHERE username =  \'Admin\'';
+		$this->create_and_execute_prepared_stmt($sql, [
+			'username' => $this->install_config->get('admin_name'),
+		]);
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	static public function get_step_count() : int
+	{
+		return 1;
+	}
+
+	/**
+	 * {@inheritdoc}
+	 */
+	public function get_task_lang_name() : string
+	{
+		return 'TASK_UPDATE_POSTS';
+	}
+}
diff --git a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php
index 9f970de6a5..c4e11cac33 100644
--- a/phpBB/phpbb/install/module/install_finish/task/install_extensions.php
+++ b/phpBB/phpbb/install/module/install_finish/task/install_extensions.php
@@ -13,21 +13,31 @@
 
 namespace phpbb\install\module\install_finish\task;
 
+use Doctrine\DBAL\Connection;
+use Doctrine\DBAL\Exception as DoctrineException;
 use phpbb\config\db;
-use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\db\driver\driver_interface;
+use phpbb\install\database_task;
+use phpbb\install\helper\config;
+use phpbb\install\helper\container_factory;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
+use phpbb\install\sequential_task;
 
 /**
  * Installs extensions that exist in ext folder upon install
  */
-class install_extensions extends \phpbb\install\task_base
+class install_extensions extends database_task
 {
+	use sequential_task;
+
 	/**
-	 * @var \phpbb\install\helper\config
+	 * @var config
 	 */
 	protected $install_config;
 
 	/**
-	 * @var \phpbb\install\helper\iohandler\iohandler_interface
+	 * @var iohandler_interface
 	 */
 	protected $iohandler;
 
@@ -49,40 +59,38 @@ class install_extensions extends \phpbb\install\task_base
 	/** @var \phpbb\extension\manager */
 	protected $extension_manager;
 
-	/** @var \Symfony\Component\Finder\Finder */
-	protected $finder;
-
 	/** @var string Extension table */
 	protected $extension_table;
 
-	/** @var \phpbb\db\driver\driver_interface */
+	/** @var Connection */
 	protected $db;
 
 	/**
 	 * Constructor
 	 *
-	 * @param \phpbb\install\helper\container_factory				$container
-	 * @param \phpbb\install\helper\config							$install_config
-	 * @param \phpbb\install\helper\iohandler\iohandler_interface	$iohandler
-	 * @param string												$phpbb_root_path phpBB root path
+	 * @param container_factory		$container
+	 * @param config				$install_config
+	 * @param database				$db_helper
+	 * @param iohandler_interface	$iohandler
 	 */
-	public function __construct(\phpbb\install\helper\container_factory $container, \phpbb\install\helper\config $install_config, \phpbb\install\helper\iohandler\iohandler_interface $iohandler, $phpbb_root_path)
+	public function __construct(
+		container_factory $container,
+		config $install_config,
+		database $db_helper,
+		iohandler_interface $iohandler)
 	{
 		$this->install_config	= $install_config;
 		$this->iohandler		= $iohandler;
-		$this->extension_table = $container->get_parameter('tables.ext');
+		$this->extension_table	= $container->get_parameter('tables.ext');
+		$this->db				= self::get_doctrine_connection($db_helper, $install_config);
 
-		$this->log				= $container->get('log');
-		$this->config			= $container->get('config');
-		$this->user				= $container->get('user');
-		$this->extension_manager = $container->get('ext.manager');
-		$this->db				= $container->get('dbal.conn');
-		$this->finder = new \Symfony\Component\Finder\Finder();
-		$this->finder->in($phpbb_root_path . 'ext/')
-			->ignoreUnreadableDirs()
-			->depth('< 3')
-			->files()
-			->name('composer.json');
+		$this->log					= $container->get('log');
+		$this->config				= $container->get('config');
+		$this->user					= $container->get('user');
+		$this->extension_manager 	= $container->get('ext.manager');
+
+		/** @var driver_interface $db */
+		$db = $container->get('dbal.conn');
 
 		/** @var \phpbb\cache\driver\driver_interface $cache */
 		$cache = $container->get('cache.driver');
@@ -90,7 +98,7 @@ class install_extensions extends \phpbb\install\task_base
 
 		global $config;
 		$config = new db(
-			$this->db,
+			$db,
 			$cache,
 			$container->get_parameter('tables.config')
 		);
@@ -103,7 +111,11 @@ class install_extensions extends \phpbb\install\task_base
 			$this->config['assets_version'] = 0;
 		}
 
-		parent::__construct(true);
+		parent::__construct(
+			$this->db,
+			$this->iohandler,
+			true
+		);
 	}
 
 	/**
@@ -113,65 +125,50 @@ class install_extensions extends \phpbb\install\task_base
 	{
 		$this->user->session_begin();
 		$this->user->setup(array('common', 'acp/common', 'cli'));
+		$all_available_extensions = $this->extension_manager->all_available();
+		$this->execute($this->install_config, $all_available_extensions);
+	}
 
+	/**
+	 * {@inheritdoc}
+	 */
+	protected function execute_step($key, $value) : void
+	{
 		$install_extensions = $this->iohandler->get_input('install-extensions', array());
 
-		$all_available_extensions = $this->extension_manager->all_available();
-		$i = $this->install_config->get('install_extensions_index', 0);
-		$available_extensions = array_slice($all_available_extensions, $i);
-
-		// Install extensions
-		foreach ($available_extensions as $ext_name => $ext_path)
+		if (!empty($install_extensions) && $install_extensions !== ['all'] && !in_array($key, $install_extensions))
 		{
-			if (!empty($install_extensions) && $install_extensions !== ['all'] && !in_array($ext_name, $install_extensions))
-			{
-				continue;
-			}
-
-			try
-			{
-				$extension = $this->extension_manager->get_extension($ext_name);
-
-				if (!$extension->is_enableable())
-				{
-					$this->iohandler->add_log_message(array('CLI_EXTENSION_NOT_ENABLEABLE', $ext_name));
-					continue;
-				}
-
-				$this->extension_manager->enable($ext_name);
-				$extensions = $this->get_extensions();
-
-				if (isset($extensions[$ext_name]) && $extensions[$ext_name]['ext_active'])
-				{
-					// Create log
-					$this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($ext_name));
-					$this->iohandler->add_success_message(array('CLI_EXTENSION_ENABLE_SUCCESS', $ext_name));
-				}
-				else
-				{
-					$this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name));
-				}
-			}
-			catch (\Exception $e)
-			{
-				// Add fail log and continue
-				$this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $ext_name));
-			}
-
-			$i++;
-
-			// Stop execution if resource limit is reached
-			if ($this->install_config->get_time_remaining() <= 0 || $this->install_config->get_memory_remaining() <= 0)
-			{
-				break;
-			}
+			return;
 		}
 
-		$this->install_config->set('install_extensions_index', $i);
-
-		if ($i < count($all_available_extensions))
+		try
 		{
-			throw new resource_limit_reached_exception();
+			$extension = $this->extension_manager->get_extension($key);
+
+			if (!$extension->is_enableable())
+			{
+				$this->iohandler->add_log_message(array('CLI_EXTENSION_NOT_ENABLEABLE', $key));
+				return;
+			}
+
+			$this->extension_manager->enable($key);
+			$extensions = $this->get_extensions();
+
+			if (isset($extensions[$key]) && $extensions[$key]['ext_active'])
+			{
+				// Create log
+				$this->log->add('admin', ANONYMOUS, '', 'LOG_EXT_ENABLE', time(), array($key));
+				$this->iohandler->add_success_message(array('CLI_EXTENSION_ENABLE_SUCCESS', $key));
+			}
+			else
+			{
+				$this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $key));
+			}
+		}
+		catch (\Exception $e)
+		{
+			// Add fail log and continue
+			$this->iohandler->add_log_message(array('CLI_EXTENSION_ENABLE_FAILURE', $key));
 		}
 	}
 
@@ -196,17 +193,19 @@ class install_extensions extends \phpbb\install\task_base
 	 *
 	 * @return array List of extensions
 	 */
-	private function get_extensions()
+	private function get_extensions() : array
 	{
-		$sql = 'SELECT *
-			FROM ' . $this->extension_table;
-
-		$result = $this->db->sql_query($sql);
-		$extensions_row = $this->db->sql_fetchrowset($result);
-		$this->db->sql_freeresult($result);
-
-		$extensions = array();
+		try
+		{
+			$extensions_row = $this->db->fetchAllAssociative('SELECT * FROM ' . $this->extension_table);
+		}
+		catch (DoctrineException $e)
+		{
+			$this->iohandler->add_error_message('INST_ERR_DB', $e->getMessage());
+			return [];
+		}
 
+		$extensions = [];
 		foreach ($extensions_row as $extension)
 		{
 			$extensions[$extension['ext_name']] = $extension;
diff --git a/phpBB/phpbb/install/sequential_task.php b/phpBB/phpbb/install/sequential_task.php
new file mode 100644
index 0000000000..bc389c272d
--- /dev/null
+++ b/phpBB/phpbb/install/sequential_task.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\install;
+
+use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\helper\config;
+
+/**
+ * Trait to execute tasks in steps with timeout management.
+ */
+trait sequential_task
+{
+	/**
+	 * Callback function to execute a unit of work.
+	 *
+	 * @param mixed $key	The array key.
+	 * @param mixed $value	The array value.
+	 */
+	abstract protected function execute_step($key, $value) : void;
+
+	/**
+	 * Execute the tasks with timeout management.
+	 *
+	 * @param config		$config			Installer config.
+	 * @param array			$data			Array of elements to iterate over.
+	 * @param string|null	$counter_name	The name of the counter or null.
+	 *
+	 * @throws resource_limit_reached_exception When resources are exhausted.
+	 */
+	protected function execute(config $config, array $data, ?string $counter_name = null) : void
+	{
+		if ($counter_name === null)
+		{
+			$counter_name = 'step_counter_' . get_class($this);
+		}
+
+		$counter = $config->get($counter_name, 0);
+		$total = count($data);
+		$data = array_slice($data, $counter);
+		foreach ($data as $key => $value)
+		{
+			if ($config->get_time_remaining() <= 0 || $config->get_memory_remaining() <= 0)
+			{
+				break;
+			}
+
+			$this->execute_step($key, $value);
+			++$counter;
+		}
+
+		$config->set($counter_name, $counter);
+
+		if ($counter < $total)
+		{
+			throw new resource_limit_reached_exception();
+		}
+	}
+}
diff --git a/tests/functions/convert_30_dbms_to_31_test.php b/tests/functions/convert_30_dbms_to_31_test.php
index 05c42610bb..e88da592a7 100644
--- a/tests/functions/convert_30_dbms_to_31_test.php
+++ b/tests/functions/convert_30_dbms_to_31_test.php
@@ -30,9 +30,7 @@ class phpbb_convert_30_dbms_to_31_test extends phpbb_test_case
 	public function test_convert_30_dbms_to_31($input)
 	{
 		$expected = "phpbb\\db\\driver\\$input";
-
-		$config_php_file = new \phpbb\config_php_file('', '');
-		$output = $config_php_file->convert_30_dbms_to_31($input);
+		$output = \phpbb\config_php_file::convert_30_dbms_to_31($input);
 
 		$this->assertEquals($expected, $output);
 	}
diff --git a/tests/test_framework/phpbb_test_case_helpers.php b/tests/test_framework/phpbb_test_case_helpers.php
index 11a5836fe1..d20d8bdf82 100644
--- a/tests/test_framework/phpbb_test_case_helpers.php
+++ b/tests/test_framework/phpbb_test_case_helpers.php
@@ -154,7 +154,7 @@ class phpbb_test_case_helpers
 			extract($config_php_file->get_all());
 
 			$config = array_merge($config, array(
-				'dbms'		=> $config_php_file->convert_30_dbms_to_31($dbms),
+				'dbms'		=> \phpbb\config_php_file::convert_30_dbms_to_31($dbms),
 				'dbhost'	=> $dbhost,
 				'dbport'	=> $dbport,
 				'dbname'	=> $dbname,
@@ -196,7 +196,7 @@ class phpbb_test_case_helpers
 		if (isset($_SERVER['PHPBB_TEST_DBMS']))
 		{
 			$config = array_merge($config, array(
-				'dbms'		=> isset($_SERVER['PHPBB_TEST_DBMS']) ? $config_php_file->convert_30_dbms_to_31($_SERVER['PHPBB_TEST_DBMS']) : '',
+				'dbms'		=> isset($_SERVER['PHPBB_TEST_DBMS']) ? \phpbb\config_php_file::convert_30_dbms_to_31($_SERVER['PHPBB_TEST_DBMS']) : '',
 				'dbhost'	=> isset($_SERVER['PHPBB_TEST_DBHOST']) ? $_SERVER['PHPBB_TEST_DBHOST'] : '',
 				'dbport'	=> isset($_SERVER['PHPBB_TEST_DBPORT']) ? $_SERVER['PHPBB_TEST_DBPORT'] : '',
 				'dbname'	=> isset($_SERVER['PHPBB_TEST_DBNAME']) ? $_SERVER['PHPBB_TEST_DBNAME'] : '',