diff --git a/.github/dependabot.yml b/.github/dependabot.yml
index 8a776ca319bccc465e60aea0a3dc3d5df6f053b0..984ad2bfe223ab232e6216b4cce2ec86a2604db9 100644
--- a/.github/dependabot.yml
+++ b/.github/dependabot.yml
@@ -1,11 +1,12 @@
 version: 2
 updates:
-- package-ecosystem: composer
-  directory: "/"
-  schedule:
-    interval: weekly
-  open-pull-requests-limit: 10
-- package-ecosystem: "github-actions"
-  directory: "/"
-  schedule:
-    interval: "weekly"
+  - package-ecosystem: "composer"
+    directory: "/"
+    schedule:
+      interval: "daily"
+    open-pull-requests-limit: 10
+
+  - package-ecosystem: "github-actions"
+    directory: "/"
+    schedule:
+      interval: "weekly"
diff --git a/.github/workflows/integrate.yaml b/.github/workflows/integrate.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..a6103633e57f5da177888963ffc40b55f73137ff
--- /dev/null
+++ b/.github/workflows/integrate.yaml
@@ -0,0 +1,60 @@
+# https://docs.github.com/en/actions
+
+name: "Integrate"
+
+on: # yamllint disable-line rule:truthy
+  push:
+    branches:
+      - "5.x"
+  pull_request: null
+  # Allow manually triggering the workflow.
+  workflow_dispatch: null
+
+jobs:
+  code-coverage:
+    name: "Code Coverage"
+    uses: "phpDocumentor/.github/.github/workflows/code-coverage.yml@main"
+    with:
+      composer-root-version: "5.x-dev"
+
+  coding-standards:
+    name: "Coding Standards"
+    uses: "phpDocumentor/.github/.github/workflows/coding-standards.yml@v0.5.0"
+    with:
+      composer-root-version: "5.x-dev"
+
+  dependency-analysis:
+    name: "Dependency analysis"
+    uses: "phpDocumentor/.github/.github/workflows/dependency-analysis.yml@v0.5.0"
+    with:
+      composer-root-version: "5.x-dev"
+
+  lint-root:
+    name: "Lint root"
+    uses: "phpDocumentor/.github/.github/workflows/lint.yml@main"
+    with:
+      composer-options: "--no-check-publish --ansi"
+
+  static-analysis:
+    name: "Static analysis"
+    uses: "phpDocumentor/.github/.github/workflows/static-analysis.yml@v0.5.0"
+    with:
+      php-extensions: "none, ctype, dom, json, mbstring, phar, simplexml, tokenizer, xml, xmlwriter, fileinfo, pcntl, posix"
+      composer-root-version: "5.x-dev"
+
+  unit-tests:
+    name: "Unit test"
+    uses: "phpDocumentor/.github/.github/workflows/continuous-integration.yml@v0.5.0"
+    with:
+      composer-root-version: "5.x-dev"
+      php-versions: "['7.4', '8.0', '8.1', '8.2', '8.3']"
+
+  bc_check:
+    name: "BC Check"
+    runs-on: "ubuntu-latest"
+    steps:
+      - uses: "actions/checkout@v3"
+      - name: "fetch tags"
+        run: "git fetch --depth=1 origin +refs/tags/*:refs/tags/*"
+      - name: "BC Check"
+        uses: "docker://nyholm/roave-bc-check-ga"
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
deleted file mode 100644
index 60ae4ff206f5c5758cd1bf7fe90fcd2553b79bdf..0000000000000000000000000000000000000000
--- a/.github/workflows/push.yml
+++ /dev/null
@@ -1,211 +0,0 @@
-on:
-  push:
-    branches:
-      - master
-  pull_request:
-  # Allow manually triggering the workflow.
-  workflow_dispatch:
-name: Qa workflow
-env:
-  phiveGPGKeys: 4AA394086372C20A,D2CCAC42F6295E7D,E82B2FB314E9906E,8A03EA3B385DBAA1
-jobs:
-  setup:
-    runs-on: ubuntu-latest
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: composer
-        uses: docker://composer
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          args: install --no-interaction --prefer-dist --optimize-autoloader
-
-      - name: composer-require-checker
-        uses: docker://phpga/composer-require-checker-ga
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          args: check --config-file ./composer-require-config.json composer.json
-
-  phpunit-with-coverage:
-    runs-on: ubuntu-latest
-    name: Unit tests
-    needs: setup
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: composer
-        uses: docker://composer
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          args: install --no-interaction --prefer-dist --optimize-autoloader
-
-      - name: PHPUnit
-        uses: docker://phpdoc/phpunit-ga:latest
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-
-      - name: Quick check code coverage level
-        run: php tests/coverage-checker.php 91
-
-  phpunit:
-    name: Unit tests for PHP version ${{ matrix.php-versions }} on ${{ matrix.operating-system }}
-    runs-on: ${{ matrix.operating-system }}
-    strategy:
-      fail-fast: false
-      matrix:
-        operating-system:
-          - ubuntu-latest
-          - windows-latest
-          - macOS-latest
-        php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1']
-    env:
-      extensions: mbstring
-      key: cache-v1 # can be any string, change to clear the extension cache.
-
-    needs:
-      - setup
-      - phpunit-with-coverage
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup cache environment
-        id: cache-env
-        uses: shivammathur/cache-extensions@v1
-        with:
-          php-version: ${{ matrix.php-versions }}
-          extensions: ${{ env.extensions }}
-          key: ${{ env.key }}
-
-      - name: Cache extensions
-        uses: actions/cache@v2.1.6
-        with:
-          path: ${{ steps.cache-env.outputs.dir }}
-          key: ${{ steps.cache-env.outputs.key }}
-
-      - name: Setup PHP
-        uses: shivammathur/setup-php@v2
-        with:
-          php-version: ${{ matrix.php-versions }}
-          extensions: ${{ env.extensions }}
-          ini-values: memory_limit=2G, display_errors=On, error_reporting=-1
-          tools: phive
-
-      - name: Install PHAR dependencies
-        env:
-          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: phive --no-progress install --copy --trust-gpg-keys ${{ env.phiveGPGKeys }} --force-accept-unsigned
-
-      - name: Install phpunit 8 for php 7.2
-        if: matrix.php-versions == '7.2'
-        env:
-          GITHUB_AUTH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        run: phive --no-progress install --copy --trust-gpg-keys ${{ env.phiveGPGKeys }} phpunit:^8.5
-
-      - name: Install Composer dependencies & cache dependencies
-        uses: "ramsey/composer-install@v1"
-        with:
-          composer-options: --optimize-autoloader
-
-      - name: Run PHPUnit
-        run: php tools/phpunit
-
-  codestyle:
-    runs-on: ubuntu-latest
-    needs: [setup, phpunit]
-    steps:
-      - uses: actions/checkout@v2
-      - name: Restore/cache vendor folder
-        uses: actions/cache@v2.1.6
-        with:
-          path: vendor
-          key: all-build-${{ hashFiles('**/composer.lock') }}
-          restore-keys: |
-            all-build-${{ hashFiles('**/composer.lock') }}
-            all-build-
-      - name: Code style check
-        uses: phpDocumentor/coding-standard@latest
-        with:
-          args: -s
-
-  phpstan:
-    runs-on: ubuntu-latest
-    needs: [setup, phpunit]
-    steps:
-      - uses: actions/checkout@v2
-      - name: composer
-        uses: docker://composer
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          args: install --no-interaction --prefer-dist --optimize-autoloader
-
-      - name: PHPStan
-        uses: phpDocumentor/phpstan-ga@0.12.9
-        env:
-          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
-        with:
-          args: analyse src --configuration phpstan.neon
-
-  psalm:
-    name: Psalm
-    runs-on: ${{ matrix.operating-system }}
-    strategy:
-      matrix:
-        operating-system:
-          - ubuntu-latest
-        php-versions: ['7.2']
-    env:
-      extensions: mbstring
-      key: cache-v1 # can be any string, change to clear the extension cache.
-
-    needs:
-      - setup
-      - phpunit
-
-    steps:
-      - uses: actions/checkout@v2
-
-      - name: Setup cache environment
-        id: cache-env
-        uses: shivammathur/cache-extensions@v1
-        with:
-          php-version: ${{ matrix.php-versions }}
-          extensions: ${{ env.extensions }}
-          key: ${{ env.key }}
-
-      - name: Cache extensions
-        uses: actions/cache@v2.1.6
-        with:
-          path: ${{ steps.cache-env.outputs.dir }}
-          key: ${{ steps.cache-env.outputs.key }}
-
-      - name: Setup PHP
-        uses: shivammathur/setup-php@v2
-        with:
-          php-version: ${{ matrix.php-versions }}
-          extensions: ${{ env.extensions }}
-          ini-values: memory_limit=2G, display_errors=On, error_reporting=-1
-
-      - name: Install Composer dependencies & cache dependencies
-        uses: "ramsey/composer-install@v1"
-        with:
-          composer-options: --optimize-autoloader
-
-      - name: Run psalm
-        run: vendor/bin/psalm.phar --output-format=github
-
-
-  bc_check:
-    name: BC Check
-    runs-on: ubuntu-latest
-    needs: [setup, phpunit]
-    steps:
-      - uses: actions/checkout@v2
-      - name: fetch tags
-        run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
-      - name: BC Check
-        uses: docker://nyholm/roave-bc-check-ga
diff --git a/.scrutinizer.yml b/.scrutinizer.yml
deleted file mode 100644
index 4c5f951187ce3d63d91d4234215e5b6e8b440c4a..0000000000000000000000000000000000000000
--- a/.scrutinizer.yml
+++ /dev/null
@@ -1,48 +0,0 @@
-before_commands:
-    - "composer install --no-dev --prefer-source"
-
-checks:
-    php:
-        excluded_dependencies:
-            - phpstan/phpstan
-
-tools:
-    external_code_coverage:
-        enabled: true
-        timeout: 300
-        filter:
-            excluded_paths: ["examples", "tests", "vendor"]
-    php_code_sniffer:
-        enabled: true
-        config:
-            standard: PSR2
-        filter:
-            paths: ["src/*", "tests/*"]
-            excluded_paths: []
-    php_cpd:
-        enabled: true
-        excluded_dirs: ["examples", "tests", "vendor"]
-    php_cs_fixer:
-        enabled: true
-        config:
-            level: all
-        filter:
-            paths: ["src/*", "tests/*"]
-    php_loc:
-        enabled: true
-        excluded_dirs: ["examples", "tests", "vendor"]
-    php_mess_detector:
-        enabled: true
-        config:
-            ruleset: phpmd.xml.dist
-            design_rules: { eval_expression: false }
-        filter:
-            paths: ["src/*"]
-    php_pdepend:
-        enabled: true
-        excluded_dirs: ["examples", "tests", "vendor"]
-    php_analyzer:
-        enabled: true
-        filter:
-            paths: ["src/*", "tests/*"]
-    sensiolabs_security_checker: true
diff --git a/.yamllint.yaml b/.yamllint.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..55695cd5633438c0829187898364f897270c49d7
--- /dev/null
+++ b/.yamllint.yaml
@@ -0,0 +1,65 @@
+extends: "default"
+
+ignore: |
+  .build/
+  .notes/
+  vendor/
+rules:
+  braces:
+    max-spaces-inside-empty: 0
+    max-spaces-inside: 1
+    min-spaces-inside-empty: 0
+    min-spaces-inside: 1
+  brackets:
+    max-spaces-inside-empty: 0
+    max-spaces-inside: 0
+    min-spaces-inside-empty: 0
+    min-spaces-inside: 0
+  colons:
+    max-spaces-after: 1
+    max-spaces-before: 0
+  commas:
+    max-spaces-after: 1
+    max-spaces-before: 0
+    min-spaces-after: 1
+  comments:
+    ignore-shebangs: true
+    min-spaces-from-content: 1
+    require-starting-space: true
+  comments-indentation: "enable"
+  document-end:
+    present: false
+  document-start:
+    present: false
+  indentation:
+    check-multi-line-strings: false
+    indent-sequences: true
+    spaces: 2
+  empty-lines:
+    max-end: 0
+    max-start: 0
+    max: 1
+  empty-values:
+    forbid-in-block-mappings: true
+    forbid-in-flow-mappings: true
+  hyphens:
+    max-spaces-after: 2
+  key-duplicates: "enable"
+  key-ordering: "disable"
+  line-length: "disable"
+  new-line-at-end-of-file: "enable"
+  new-lines:
+    type: "unix"
+  octal-values:
+    forbid-implicit-octal: true
+  quoted-strings:
+    quote-type: "double"
+  trailing-spaces: "enable"
+  truthy:
+    allowed-values:
+      - "false"
+      - "true"
+
+yaml-files:
+  - "*.yaml"
+  - "*.yml"
diff --git a/Makefile b/Makefile
index 1c92888d23e707bdc0d3db021d9249566ac63c51..9b28eb9ec1505072262484847160263780270d77 100644
--- a/Makefile
+++ b/Makefile
@@ -1,37 +1,43 @@
-.PHONY: install-phive
-install-phive:
-	mkdir tools; \
-	wget -O tools/phive.phar https://phar.io/releases/phive.phar; \
-	wget -O tools/phive.phar.asc https://phar.io/releases/phive.phar.asc; \
-	gpg --keyserver pool.sks-keyservers.net --recv-keys 0x9D8A98B29B2D5D79; \
-	gpg --verify tools/phive.phar.asc tools/phive.phar; \
-	chmod +x tools/phive.phar
-
-.PHONY: setup
-setup: install-phive
-	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phar-ga:latest php tools/phive.phar install --force-accept-unsigned
-
-.PHONY: phpcs
-phpcs:
-	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest -s
-
-.PHONY: phpcbf
-phpcbf:
-	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest phpcbf
+.PHONY: help
+help: ## Displays this list of targets with descriptions
+	@grep -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}'
+
+.PHONY: code-style
+code-style:
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest -d memory_limit=1024M -s
 
-.PHONY: phpstan
-phpstan:
-	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpstan-ga:latest analyse src --no-progress --configuration phpstan.neon
+.PHONY: fix-code-style
+fix-code-style:
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project phpdoc/phpcs-ga:latest phpcbf
 
-.PHONY: psalm
-psalm:
-	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.3 vendor/bin/psalm.phar
+.PHONY: static-code-analysis
+static-code-analysis: vendor ## Runs a static code analysis with phpstan/phpstan and vimeo/psalm
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpstan --configuration=phpstan.neon
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/psalm
 
 .PHONY: test
-test:
-	docker run -it --rm -v${CURDIR}:/github/workspace phpdoc/phpunit-ga
-	docker run -it --rm -v${CURDIR}:/data -w /data php:7.2 -f ./tests/coverage-checker.php 90
+test: test-unit ## Runs all test suites with phpunit/phpunit
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit
 
-.PHONY: pre-commit-test
-pre-commit-test: test phpcs phpstan psalm
+.PHONY: test-unit
+test-unit: ## Runs unit tests with phpunit/phpunit
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/phpunit --testsuite=unit
+
+.PHONY: dependency-analysis
+dependency-analysis: vendor ## Runs a dependency analysis with maglnet/composer-require-checker
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 .phive/composer-require-checker check --config-file=/opt/project/composer-require-checker.json
 
+vendor: composer.json composer.lock
+	composer validate --no-check-publish
+	composer install --no-interaction --no-progress
+
+.PHONY: benchmark
+benchmark:
+	docker run -it --rm -v${CURDIR}:/opt/project -w /opt/project php:7.4-cli tools/phpbench run
+
+.PHONY: rector
+rector: ## Refactor code using rector
+	docker run -it --rm -v${PWD}:/opt/project -w /opt/project php:7.4 vendor/bin/rector process
+
+.PHONY: pre-commit-test
+pre-commit-test: fix-code-style test code-style static-code-analysis
diff --git a/README.md b/README.md
index 51f10883b731b6e0aa93e3479b304359fa756306..a0fe02ba769176a17157f4146639e82b08d0385b 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,5 @@
 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
 ![Qa workflow](https://github.com/phpDocumentor/ReflectionDocBlock/workflows/Qa%20workflow/badge.svg)
-[![Coveralls Coverage](https://img.shields.io/coveralls/github/phpDocumentor/ReflectionDocBlock.svg)](https://coveralls.io/github/phpDocumentor/ReflectionDocBlock?branch=master)
 [![Scrutinizer Code Coverage](https://img.shields.io/scrutinizer/coverage/g/phpDocumentor/ReflectionDocBlock.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)
 [![Scrutinizer Code Quality](https://img.shields.io/scrutinizer/g/phpDocumentor/ReflectionDocBlock.svg)](https://scrutinizer-ci.com/g/phpDocumentor/ReflectionDocBlock/?branch=master)
 [![Stable Version](https://img.shields.io/packagist/v/phpdocumentor/reflection-docblock.svg)](https://packagist.org/packages/phpdocumentor/reflection-docblock)
diff --git a/composer-require-config.json b/composer-require-checker.json
similarity index 100%
rename from composer-require-config.json
rename to composer-require-checker.json
diff --git a/composer.json b/composer.json
index d90763024dde47c0e19f7184182feb9d17290244..cf8f49d3705fb90dba61886a196988f6d550a92d 100644
--- a/composer.json
+++ b/composer.json
@@ -10,19 +10,26 @@
         },
         {
             "name": "Jaap van Otterdijk",
-            "email": "account@ijaap.nl"
+            "email": "opensource@ijaap.nl"
         }
     ],
     "require": {
-        "php": "^7.2 || ^8.0",
-        "phpdocumentor/type-resolver": "^1.3",
+        "php": "^7.4 || ^8.0",
+        "phpdocumentor/type-resolver": "^1.7",
         "webmozart/assert": "^1.9.1",
         "phpdocumentor/reflection-common": "^2.2",
-        "ext-filter": "*"
+        "ext-filter": "*",
+        "phpstan/phpdoc-parser": "^1.7",
+        "doctrine/deprecations": "^1.1"
     },
     "require-dev": {
-        "mockery/mockery": "~1.3.2",
-        "psalm/phar": "^4.8"
+        "mockery/mockery": "~1.3.5",
+        "phpunit/phpunit": "^9.5",
+        "phpstan/phpstan": "^1.8",
+        "phpstan/phpstan-mockery": "^1.1",
+        "phpstan/extension-installer": "^1.1",
+        "phpstan/phpstan-webmozart-assert": "^1.2",
+        "vimeo/psalm": "^5.13"
     },
     "autoload": {
         "psr-4": {
@@ -34,6 +41,14 @@
             "phpDocumentor\\Reflection\\": ["tests/unit", "tests/integration"]
         }
     },
+    "config": {
+        "platform": {
+            "php":"7.4.0"
+        },
+        "allow-plugins": {
+            "phpstan/extension-installer": true
+        }
+    },
     "extra": {
         "branch-alias": {
             "dev-master": "5.x-dev"
diff --git a/composer.lock b/composer.lock
index 69df42963fb12e9180962b2a4e3be397322880ca..25557a935fcc1b422b856a5d5b5ecd0b7fc5662a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,55 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "f1e7818879f1626c05926f50c2c96f44",
+    "content-hash": "be391d67a41b2aa6ba500afca03e00a5",
     "packages": [
+        {
+            "name": "doctrine/deprecations",
+            "version": "1.1.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/deprecations.git",
+                "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+                "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^9",
+                "phpstan/phpstan": "1.4.10 || 1.10.15",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "psalm/plugin-phpunit": "0.18.4",
+                "psr/log": "^1 || ^2 || ^3",
+                "vimeo/psalm": "4.30.0 || 5.12.0"
+            },
+            "suggest": {
+                "psr/log": "Allows logging deprecations via PSR-3 logger implementation"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.",
+            "homepage": "https://www.doctrine-project.org/",
+            "support": {
+                "issues": "https://github.com/doctrine/deprecations/issues",
+                "source": "https://github.com/doctrine/deprecations/tree/1.1.3"
+            },
+            "time": "2024-01-30T19:34:25+00:00"
+        },
         {
             "name": "phpdocumentor/reflection-common",
             "version": "2.2.0",
@@ -61,25 +108,33 @@
         },
         {
             "name": "phpdocumentor/type-resolver",
-            "version": "1.5.1",
+            "version": "1.8.2",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpDocumentor/TypeResolver.git",
-                "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae"
+                "reference": "153ae662783729388a584b4361f2545e4d841e3c"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae",
-                "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae",
+                "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c",
+                "reference": "153ae662783729388a584b4361f2545e4d841e3c",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.2 || ^8.0",
-                "phpdocumentor/reflection-common": "^2.0"
+                "doctrine/deprecations": "^1.0",
+                "php": "^7.3 || ^8.0",
+                "phpdocumentor/reflection-common": "^2.0",
+                "phpstan/phpdoc-parser": "^1.13"
             },
             "require-dev": {
                 "ext-tokenizer": "*",
-                "psalm/phar": "^4.8"
+                "phpbench/phpbench": "^1.2",
+                "phpstan/extension-installer": "^1.1",
+                "phpstan/phpstan": "^1.8",
+                "phpstan/phpstan-phpunit": "^1.1",
+                "phpunit/phpunit": "^9.5",
+                "rector/rector": "^0.13.9",
+                "vimeo/psalm": "^4.25"
             },
             "type": "library",
             "extra": {
@@ -105,106 +160,72 @@
             "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/1.5.1"
+                "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2"
             },
-            "time": "2021-10-02T14:08:47+00:00"
+            "time": "2024-02-23T11:10:43+00:00"
         },
         {
-            "name": "symfony/polyfill-ctype",
-            "version": "v1.23.0",
+            "name": "phpstan/phpdoc-parser",
+            "version": "1.13.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/symfony/polyfill-ctype.git",
-                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce"
+                "url": "https://github.com/phpstan/phpdoc-parser.git",
+                "reference": "33aefcdab42900e36366d0feab6206e2dd68f947"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce",
-                "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce",
+                "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/33aefcdab42900e36366d0feab6206e2dd68f947",
+                "reference": "33aefcdab42900e36366d0feab6206e2dd68f947",
                 "shasum": ""
             },
             "require": {
-                "php": ">=7.1"
+                "php": "^7.2 || ^8.0"
             },
-            "suggest": {
-                "ext-ctype": "For best performance"
+            "require-dev": {
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/extension-installer": "^1.0",
+                "phpstan/phpstan": "^1.5",
+                "phpstan/phpstan-phpunit": "^1.1",
+                "phpstan/phpstan-strict-rules": "^1.0",
+                "phpunit/phpunit": "^9.5",
+                "symfony/process": "^5.2"
             },
             "type": "library",
-            "extra": {
-                "branch-alias": {
-                    "dev-main": "1.23-dev"
-                },
-                "thanks": {
-                    "name": "symfony/polyfill",
-                    "url": "https://github.com/symfony/polyfill"
-                }
-            },
             "autoload": {
                 "psr-4": {
-                    "Symfony\\Polyfill\\Ctype\\": ""
-                },
-                "files": [
-                    "bootstrap.php"
-                ]
+                    "PHPStan\\PhpDocParser\\": [
+                        "src/"
+                    ]
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
-            "authors": [
-                {
-                    "name": "Gert de Pagter",
-                    "email": "BackEndTea@gmail.com"
-                },
-                {
-                    "name": "Symfony Community",
-                    "homepage": "https://symfony.com/contributors"
-                }
-            ],
-            "description": "Symfony polyfill for ctype functions",
-            "homepage": "https://symfony.com",
-            "keywords": [
-                "compatibility",
-                "ctype",
-                "polyfill",
-                "portable"
-            ],
+            "description": "PHPDoc parser with support for nullable, intersection and generic types",
             "support": {
-                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0"
+                "issues": "https://github.com/phpstan/phpdoc-parser/issues",
+                "source": "https://github.com/phpstan/phpdoc-parser/tree/1.13.0"
             },
-            "funding": [
-                {
-                    "url": "https://symfony.com/sponsor",
-                    "type": "custom"
-                },
-                {
-                    "url": "https://github.com/fabpot",
-                    "type": "github"
-                },
-                {
-                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
-                    "type": "tidelift"
-                }
-            ],
-            "time": "2021-02-19T12:13:01+00:00"
+            "time": "2022-10-21T09:57:39+00:00"
         },
         {
             "name": "webmozart/assert",
-            "version": "1.10.0",
+            "version": "1.11.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/webmozarts/assert.git",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
-                "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
+                "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991",
+                "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.2 || ^8.0",
-                "symfony/polyfill-ctype": "^1.8"
+                "ext-ctype": "*",
+                "php": "^7.2 || ^8.0"
             },
             "conflict": {
                 "phpstan/phpstan": "<0.12.20",
@@ -242,177 +263,3868 @@
             ],
             "support": {
                 "issues": "https://github.com/webmozarts/assert/issues",
-                "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+                "source": "https://github.com/webmozarts/assert/tree/1.11.0"
             },
-            "time": "2021-03-09T10:59:23+00:00"
+            "time": "2022-06-03T18:03:27+00:00"
         }
     ],
     "packages-dev": [
         {
-            "name": "hamcrest/hamcrest-php",
-            "version": "v2.0.1",
+            "name": "amphp/amp",
+            "version": "v2.6.2",
             "source": {
                 "type": "git",
-                "url": "https://github.com/hamcrest/hamcrest-php.git",
-                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
+                "url": "https://github.com/amphp/amp.git",
+                "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
-                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "url": "https://api.github.com/repos/amphp/amp/zipball/9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
+                "reference": "9d5100cebffa729aaffecd3ad25dc5aeea4f13bb",
                 "shasum": ""
             },
             "require": {
-                "php": "^5.3|^7.0|^8.0"
-            },
-            "replace": {
-                "cordoval/hamcrest-php": "*",
-                "davedevelopment/hamcrest-php": "*",
-                "kodova/hamcrest-php": "*"
+                "php": ">=7.1"
             },
             "require-dev": {
-                "phpunit/php-file-iterator": "^1.4 || ^2.0",
-                "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
+                "amphp/php-cs-fixer-config": "dev-master",
+                "amphp/phpunit-util": "^1",
+                "ext-json": "*",
+                "jetbrains/phpstorm-stubs": "^2019.3",
+                "phpunit/phpunit": "^7 | ^8 | ^9",
+                "psalm/phar": "^3.11@dev",
+                "react/promise": "^2"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "2.1-dev"
+                    "dev-master": "2.x-dev"
                 }
             },
             "autoload": {
-                "classmap": [
-                    "hamcrest"
-                ]
+                "files": [
+                    "lib/functions.php",
+                    "lib/Internal/functions.php"
+                ],
+                "psr-4": {
+                    "Amp\\": "lib"
+                }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "BSD-3-Clause"
+                "MIT"
             ],
-            "description": "This is the PHP port of Hamcrest Matchers",
+            "authors": [
+                {
+                    "name": "Daniel Lowrey",
+                    "email": "rdlowrey@php.net"
+                },
+                {
+                    "name": "Aaron Piotrowski",
+                    "email": "aaron@trowski.com"
+                },
+                {
+                    "name": "Bob Weinand",
+                    "email": "bobwei9@hotmail.com"
+                },
+                {
+                    "name": "Niklas Keller",
+                    "email": "me@kelunik.com"
+                }
+            ],
+            "description": "A non-blocking concurrency framework for PHP applications.",
+            "homepage": "https://amphp.org/amp",
             "keywords": [
-                "test"
+                "async",
+                "asynchronous",
+                "awaitable",
+                "concurrency",
+                "event",
+                "event-loop",
+                "future",
+                "non-blocking",
+                "promise"
             ],
             "support": {
-                "issues": "https://github.com/hamcrest/hamcrest-php/issues",
-                "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+                "irc": "irc://irc.freenode.org/amphp",
+                "issues": "https://github.com/amphp/amp/issues",
+                "source": "https://github.com/amphp/amp/tree/v2.6.2"
             },
-            "time": "2020-07-09T08:09:16+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/amphp",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-02-20T17:52:18+00:00"
         },
         {
-            "name": "mockery/mockery",
-            "version": "1.3.5",
+            "name": "amphp/byte-stream",
+            "version": "v1.8.1",
             "source": {
                 "type": "git",
-                "url": "https://github.com/mockery/mockery.git",
-                "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d"
+                "url": "https://github.com/amphp/byte-stream.git",
+                "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/mockery/mockery/zipball/472fa8ca4e55483d55ee1e73c963718c4393791d",
-                "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d",
+                "url": "https://api.github.com/repos/amphp/byte-stream/zipball/acbd8002b3536485c997c4e019206b3f10ca15bd",
+                "reference": "acbd8002b3536485c997c4e019206b3f10ca15bd",
                 "shasum": ""
             },
             "require": {
-                "hamcrest/hamcrest-php": "^2.0.1",
-                "lib-pcre": ">=7.0",
-                "php": ">=5.6.0"
+                "amphp/amp": "^2",
+                "php": ">=7.1"
             },
             "require-dev": {
-                "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
+                "amphp/php-cs-fixer-config": "dev-master",
+                "amphp/phpunit-util": "^1.4",
+                "friendsofphp/php-cs-fixer": "^2.3",
+                "jetbrains/phpstorm-stubs": "^2019.3",
+                "phpunit/phpunit": "^6 || ^7 || ^8",
+                "psalm/phar": "^3.11.4"
             },
             "type": "library",
             "extra": {
                 "branch-alias": {
-                    "dev-master": "1.3.x-dev"
+                    "dev-master": "1.x-dev"
                 }
             },
             "autoload": {
-                "psr-0": {
-                    "Mockery": "library/"
+                "files": [
+                    "lib/functions.php"
+                ],
+                "psr-4": {
+                    "Amp\\ByteStream\\": "lib"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
-                "BSD-3-Clause"
+                "MIT"
             ],
             "authors": [
                 {
-                    "name": "Pádraic Brady",
-                    "email": "padraic.brady@gmail.com",
-                    "homepage": "http://blog.astrumfutura.com"
+                    "name": "Aaron Piotrowski",
+                    "email": "aaron@trowski.com"
                 },
                 {
-                    "name": "Dave Marshall",
-                    "email": "dave.marshall@atstsolutions.co.uk",
-                    "homepage": "http://davedevelopment.co.uk"
+                    "name": "Niklas Keller",
+                    "email": "me@kelunik.com"
                 }
             ],
-            "description": "Mockery is a simple yet flexible PHP mock object framework",
-            "homepage": "https://github.com/mockery/mockery",
+            "description": "A stream abstraction to make working with non-blocking I/O simple.",
+            "homepage": "http://amphp.org/byte-stream",
             "keywords": [
-                "BDD",
-                "TDD",
-                "library",
-                "mock",
-                "mock objects",
-                "mockery",
-                "stub",
-                "test",
-                "test double",
-                "testing"
+                "amp",
+                "amphp",
+                "async",
+                "io",
+                "non-blocking",
+                "stream"
             ],
             "support": {
-                "issues": "https://github.com/mockery/mockery/issues",
-                "source": "https://github.com/mockery/mockery/tree/1.3.5"
+                "irc": "irc://irc.freenode.org/amphp",
+                "issues": "https://github.com/amphp/byte-stream/issues",
+                "source": "https://github.com/amphp/byte-stream/tree/v1.8.1"
             },
-            "time": "2021-09-13T15:33:03+00:00"
+            "funding": [
+                {
+                    "url": "https://github.com/amphp",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-03-30T17:13:30+00:00"
         },
         {
-            "name": "psalm/phar",
-            "version": "4.10.0",
+            "name": "composer/pcre",
+            "version": "3.0.0",
             "source": {
                 "type": "git",
-                "url": "https://github.com/psalm/phar.git",
-                "reference": "79c5b2210e1a1cabeee671db1160c96869572d08"
+                "url": "https://github.com/composer/pcre.git",
+                "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/psalm/phar/zipball/79c5b2210e1a1cabeee671db1160c96869572d08",
-                "reference": "79c5b2210e1a1cabeee671db1160c96869572d08",
+                "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd",
+                "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd",
                 "shasum": ""
             },
             "require": {
-                "php": "^7.1 || ^8.0"
+                "php": "^7.4 || ^8.0"
             },
-            "conflict": {
-                "vimeo/psalm": "*"
+            "require-dev": {
+                "phpstan/phpstan": "^1.3",
+                "phpstan/phpstan-strict-rules": "^1.1",
+                "symfony/phpunit-bridge": "^5"
             },
-            "bin": [
-                "psalm.phar"
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Pcre\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                }
+            ],
+            "description": "PCRE wrapping library that offers type-safe preg_* replacements.",
+            "keywords": [
+                "PCRE",
+                "preg",
+                "regex",
+                "regular expression"
+            ],
+            "support": {
+                "issues": "https://github.com/composer/pcre/issues",
+                "source": "https://github.com/composer/pcre/tree/3.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
             ],
+            "time": "2022-02-25T20:21:48+00:00"
+        },
+        {
+            "name": "composer/semver",
+            "version": "3.3.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/semver.git",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3.2 || ^7.0 || ^8.0"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^1.4",
+                "symfony/phpunit-bridge": "^4.2 || ^5"
+            },
             "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Composer\\Semver\\": "src"
+                }
+            },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "MIT"
             ],
-            "description": "Composer-based Psalm Phar",
+            "authors": [
+                {
+                    "name": "Nils Adermann",
+                    "email": "naderman@naderman.de",
+                    "homepage": "http://www.naderman.de"
+                },
+                {
+                    "name": "Jordi Boggiano",
+                    "email": "j.boggiano@seld.be",
+                    "homepage": "http://seld.be"
+                },
+                {
+                    "name": "Rob Bast",
+                    "email": "rob.bast@gmail.com",
+                    "homepage": "http://robbast.nl"
+                }
+            ],
+            "description": "Semver library that offers utilities, version constraint parsing and validation.",
+            "keywords": [
+                "semantic",
+                "semver",
+                "validation",
+                "versioning"
+            ],
             "support": {
-                "issues": "https://github.com/psalm/phar/issues",
-                "source": "https://github.com/psalm/phar/tree/4.10.0"
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/semver/issues",
+                "source": "https://github.com/composer/semver/tree/3.3.2"
             },
-            "time": "2021-09-05T00:07:08+00:00"
-        }
-    ],
-    "aliases": [],
-    "minimum-stability": "stable",
-    "stability-flags": [],
-    "prefer-stable": false,
-    "prefer-lowest": false,
-    "platform": {
-        "php": "^7.2 || ^8.0",
-        "ext-filter": "*"
-    },
-    "platform-dev": [],
-    "plugin-api-version": "2.1.0"
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-04-01T19:23:25+00:00"
+        },
+        {
+            "name": "composer/xdebug-handler",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/composer/xdebug-handler.git",
+                "reference": "ced299686f41dce890debac69273b47ffe98a40c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c",
+                "reference": "ced299686f41dce890debac69273b47ffe98a40c",
+                "shasum": ""
+            },
+            "require": {
+                "composer/pcre": "^1 || ^2 || ^3",
+                "php": "^7.2.5 || ^8.0",
+                "psr/log": "^1 || ^2 || ^3"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "^1.0",
+                "phpstan/phpstan-strict-rules": "^1.1",
+                "symfony/phpunit-bridge": "^6.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Composer\\XdebugHandler\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "John Stevenson",
+                    "email": "john-stevenson@blueyonder.co.uk"
+                }
+            ],
+            "description": "Restarts a process without Xdebug.",
+            "keywords": [
+                "Xdebug",
+                "performance"
+            ],
+            "support": {
+                "irc": "irc://irc.freenode.org/composer",
+                "issues": "https://github.com/composer/xdebug-handler/issues",
+                "source": "https://github.com/composer/xdebug-handler/tree/3.0.3"
+            },
+            "funding": [
+                {
+                    "url": "https://packagist.com",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/composer",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/composer/composer",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-02-25T21:32:43+00:00"
+        },
+        {
+            "name": "dnoegel/php-xdg-base-dir",
+            "version": "v0.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/dnoegel/php-xdg-base-dir.git",
+                "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/dnoegel/php-xdg-base-dir/zipball/8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+                "reference": "8f8a6e48c5ecb0f991c2fdcf5f154a47d85f9ffd",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.2"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~7.0|~6.0|~5.0|~4.8.35"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "XdgBaseDir\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "implementation of xdg base directory specification for php",
+            "support": {
+                "issues": "https://github.com/dnoegel/php-xdg-base-dir/issues",
+                "source": "https://github.com/dnoegel/php-xdg-base-dir/tree/v0.1.1"
+            },
+            "time": "2019-12-04T15:06:13+00:00"
+        },
+        {
+            "name": "doctrine/instantiator",
+            "version": "1.4.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/doctrine/instantiator.git",
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc",
+                "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "require-dev": {
+                "doctrine/coding-standard": "^9",
+                "ext-pdo": "*",
+                "ext-phar": "*",
+                "phpbench/phpbench": "^0.16 || ^1",
+                "phpstan/phpstan": "^1.4",
+                "phpstan/phpstan-phpunit": "^1",
+                "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5",
+                "vimeo/psalm": "^4.22"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Marco Pivetta",
+                    "email": "ocramius@gmail.com",
+                    "homepage": "https://ocramius.github.io/"
+                }
+            ],
+            "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
+            "homepage": "https://www.doctrine-project.org/projects/instantiator.html",
+            "keywords": [
+                "constructor",
+                "instantiate"
+            ],
+            "support": {
+                "issues": "https://github.com/doctrine/instantiator/issues",
+                "source": "https://github.com/doctrine/instantiator/tree/1.4.1"
+            },
+            "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%2Finstantiator",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-03-03T08:28:38+00:00"
+        },
+        {
+            "name": "felixfbecker/advanced-json-rpc",
+            "version": "v3.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/felixfbecker/php-advanced-json-rpc.git",
+                "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/felixfbecker/php-advanced-json-rpc/zipball/b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+                "reference": "b5f37dbff9a8ad360ca341f3240dc1c168b45447",
+                "shasum": ""
+            },
+            "require": {
+                "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+                "php": "^7.1 || ^8.0",
+                "phpdocumentor/reflection-docblock": "^4.3.4 || ^5.0.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^7.0 || ^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "AdvancedJsonRpc\\": "lib/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "ISC"
+            ],
+            "authors": [
+                {
+                    "name": "Felix Becker",
+                    "email": "felix.b@outlook.com"
+                }
+            ],
+            "description": "A more advanced JSONRPC implementation",
+            "support": {
+                "issues": "https://github.com/felixfbecker/php-advanced-json-rpc/issues",
+                "source": "https://github.com/felixfbecker/php-advanced-json-rpc/tree/v3.2.1"
+            },
+            "time": "2021-06-11T22:34:44+00:00"
+        },
+        {
+            "name": "felixfbecker/language-server-protocol",
+            "version": "v1.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/felixfbecker/php-language-server-protocol.git",
+                "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/felixfbecker/php-language-server-protocol/zipball/6e82196ffd7c62f7794d778ca52b69feec9f2842",
+                "reference": "6e82196ffd7c62f7794d778ca52b69feec9f2842",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpstan/phpstan": "*",
+                "squizlabs/php_codesniffer": "^3.1",
+                "vimeo/psalm": "^4.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "LanguageServerProtocol\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "ISC"
+            ],
+            "authors": [
+                {
+                    "name": "Felix Becker",
+                    "email": "felix.b@outlook.com"
+                }
+            ],
+            "description": "PHP classes for the Language Server Protocol",
+            "keywords": [
+                "language",
+                "microsoft",
+                "php",
+                "server"
+            ],
+            "support": {
+                "issues": "https://github.com/felixfbecker/php-language-server-protocol/issues",
+                "source": "https://github.com/felixfbecker/php-language-server-protocol/tree/v1.5.2"
+            },
+            "time": "2022-03-02T22:36:06+00:00"
+        },
+        {
+            "name": "fidry/cpu-core-counter",
+            "version": "0.5.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theofidry/cpu-core-counter.git",
+                "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
+                "reference": "b58e5a3933e541dc286cc91fc4f3898bbc6f1623",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "require-dev": {
+                "fidry/makefile": "^0.2.0",
+                "phpstan/extension-installer": "^1.2.0",
+                "phpstan/phpstan": "^1.9.2",
+                "phpstan/phpstan-deprecation-rules": "^1.0.0",
+                "phpstan/phpstan-phpunit": "^1.2.2",
+                "phpstan/phpstan-strict-rules": "^1.4.4",
+                "phpunit/phpunit": "^9.5.26 || ^8.5.31",
+                "theofidry/php-cs-fixer-config": "^1.0",
+                "webmozarts/strict-phpunit": "^7.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Fidry\\CpuCoreCounter\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Théo FIDRY",
+                    "email": "theo.fidry@gmail.com"
+                }
+            ],
+            "description": "Tiny utility to get the number of CPU cores.",
+            "keywords": [
+                "CPU",
+                "core"
+            ],
+            "support": {
+                "issues": "https://github.com/theofidry/cpu-core-counter/issues",
+                "source": "https://github.com/theofidry/cpu-core-counter/tree/0.5.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/theofidry",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-12-24T12:35:10+00:00"
+        },
+        {
+            "name": "hamcrest/hamcrest-php",
+            "version": "v2.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/hamcrest/hamcrest-php.git",
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^5.3|^7.0|^8.0"
+            },
+            "replace": {
+                "cordoval/hamcrest-php": "*",
+                "davedevelopment/hamcrest-php": "*",
+                "kodova/hamcrest-php": "*"
+            },
+            "require-dev": {
+                "phpunit/php-file-iterator": "^1.4 || ^2.0",
+                "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "hamcrest"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "description": "This is the PHP port of Hamcrest Matchers",
+            "keywords": [
+                "test"
+            ],
+            "support": {
+                "issues": "https://github.com/hamcrest/hamcrest-php/issues",
+                "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1"
+            },
+            "time": "2020-07-09T08:09:16+00:00"
+        },
+        {
+            "name": "mockery/mockery",
+            "version": "1.3.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/mockery/mockery.git",
+                "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/mockery/mockery/zipball/472fa8ca4e55483d55ee1e73c963718c4393791d",
+                "reference": "472fa8ca4e55483d55ee1e73c963718c4393791d",
+                "shasum": ""
+            },
+            "require": {
+                "hamcrest/hamcrest-php": "^2.0.1",
+                "lib-pcre": ">=7.0",
+                "php": ">=5.6.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^5.7.10|^6.5|^7.5|^8.5|^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.3.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-0": {
+                    "Mockery": "library/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Pádraic Brady",
+                    "email": "padraic.brady@gmail.com",
+                    "homepage": "http://blog.astrumfutura.com"
+                },
+                {
+                    "name": "Dave Marshall",
+                    "email": "dave.marshall@atstsolutions.co.uk",
+                    "homepage": "http://davedevelopment.co.uk"
+                }
+            ],
+            "description": "Mockery is a simple yet flexible PHP mock object framework",
+            "homepage": "https://github.com/mockery/mockery",
+            "keywords": [
+                "BDD",
+                "TDD",
+                "library",
+                "mock",
+                "mock objects",
+                "mockery",
+                "stub",
+                "test",
+                "test double",
+                "testing"
+            ],
+            "support": {
+                "issues": "https://github.com/mockery/mockery/issues",
+                "source": "https://github.com/mockery/mockery/tree/1.3.5"
+            },
+            "time": "2021-09-13T15:33:03+00:00"
+        },
+        {
+            "name": "myclabs/deep-copy",
+            "version": "1.11.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/myclabs/DeepCopy.git",
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.1 || ^8.0"
+            },
+            "conflict": {
+                "doctrine/collections": "<1.6.8",
+                "doctrine/common": "<2.13.3 || >=3,<3.2.2"
+            },
+            "require-dev": {
+                "doctrine/collections": "^1.6.8",
+                "doctrine/common": "^2.13.3 || ^3.2.2",
+                "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "src/DeepCopy/deep_copy.php"
+                ],
+                "psr-4": {
+                    "DeepCopy\\": "src/DeepCopy/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Create deep copies (clones) of your objects",
+            "keywords": [
+                "clone",
+                "copy",
+                "duplicate",
+                "object",
+                "object graph"
+            ],
+            "support": {
+                "issues": "https://github.com/myclabs/DeepCopy/issues",
+                "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0"
+            },
+            "funding": [
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-03-03T13:19:32+00:00"
+        },
+        {
+            "name": "netresearch/jsonmapper",
+            "version": "v4.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/cweiske/jsonmapper.git",
+                "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/cweiske/jsonmapper/zipball/8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
+                "reference": "8bbc021a8edb2e4a7ea2f8ad4fa9ec9dce2fcb8d",
+                "shasum": ""
+            },
+            "require": {
+                "ext-json": "*",
+                "ext-pcre": "*",
+                "ext-reflection": "*",
+                "ext-spl": "*",
+                "php": ">=7.1"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "~7.5 || ~8.0 || ~9.0",
+                "squizlabs/php_codesniffer": "~3.5"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-0": {
+                    "JsonMapper": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "OSL-3.0"
+            ],
+            "authors": [
+                {
+                    "name": "Christian Weiske",
+                    "email": "cweiske@cweiske.de",
+                    "homepage": "http://github.com/cweiske/jsonmapper/",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Map nested JSON structures onto PHP classes",
+            "support": {
+                "email": "cweiske@cweiske.de",
+                "issues": "https://github.com/cweiske/jsonmapper/issues",
+                "source": "https://github.com/cweiske/jsonmapper/tree/v4.0.0"
+            },
+            "time": "2020-12-01T19:48:11+00:00"
+        },
+        {
+            "name": "nikic/php-parser",
+            "version": "v4.14.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/nikic/PHP-Parser.git",
+                "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1",
+                "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1",
+                "shasum": ""
+            },
+            "require": {
+                "ext-tokenizer": "*",
+                "php": ">=7.0"
+            },
+            "require-dev": {
+                "ircmaxell/php-yacc": "^0.0.7",
+                "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+            },
+            "bin": [
+                "bin/php-parse"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.9-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PhpParser\\": "lib/PhpParser"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Nikita Popov"
+                }
+            ],
+            "description": "A PHP parser written in PHP",
+            "keywords": [
+                "parser",
+                "php"
+            ],
+            "support": {
+                "issues": "https://github.com/nikic/PHP-Parser/issues",
+                "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0"
+            },
+            "time": "2022-05-31T20:59:12+00:00"
+        },
+        {
+            "name": "phar-io/manifest",
+            "version": "2.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/manifest.git",
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53",
+                "reference": "97803eca37d319dfa7826cc2437fc020857acb53",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-phar": "*",
+                "ext-xmlwriter": "*",
+                "phar-io/version": "^3.0.1",
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0.x-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
+            "support": {
+                "issues": "https://github.com/phar-io/manifest/issues",
+                "source": "https://github.com/phar-io/manifest/tree/2.0.3"
+            },
+            "time": "2021-07-20T11:28:43+00:00"
+        },
+        {
+            "name": "phar-io/version",
+            "version": "3.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phar-io/version.git",
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+                "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Heuer",
+                    "email": "sebastian@phpeople.de",
+                    "role": "Developer"
+                },
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Library for handling version information and constraints",
+            "support": {
+                "issues": "https://github.com/phar-io/version/issues",
+                "source": "https://github.com/phar-io/version/tree/3.2.1"
+            },
+            "time": "2022-02-21T01:04:05+00:00"
+        },
+        {
+            "name": "phpstan/extension-installer",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/extension-installer.git",
+                "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
+                "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051",
+                "shasum": ""
+            },
+            "require": {
+                "composer-plugin-api": "^1.1 || ^2.0",
+                "php": "^7.1 || ^8.0",
+                "phpstan/phpstan": ">=0.11.6"
+            },
+            "require-dev": {
+                "composer/composer": "^1.8",
+                "phing/phing": "^2.16.3",
+                "php-parallel-lint/php-parallel-lint": "^1.2.0",
+                "phpstan/phpstan-strict-rules": "^0.11 || ^0.12"
+            },
+            "type": "composer-plugin",
+            "extra": {
+                "class": "PHPStan\\ExtensionInstaller\\Plugin"
+            },
+            "autoload": {
+                "psr-4": {
+                    "PHPStan\\ExtensionInstaller\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "Composer plugin for automatic installation of PHPStan extensions",
+            "support": {
+                "issues": "https://github.com/phpstan/extension-installer/issues",
+                "source": "https://github.com/phpstan/extension-installer/tree/1.1.0"
+            },
+            "time": "2020-12-13T13:06:13+00:00"
+        },
+        {
+            "name": "phpstan/phpstan",
+            "version": "1.8.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpstan.git",
+                "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c",
+                "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2|^8.0"
+            },
+            "conflict": {
+                "phpstan/phpstan-shim": "*"
+            },
+            "bin": [
+                "phpstan",
+                "phpstan.phar"
+            ],
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPStan - PHP Static Analysis Tool",
+            "support": {
+                "issues": "https://github.com/phpstan/phpstan/issues",
+                "source": "https://github.com/phpstan/phpstan/tree/1.8.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/ondrejmirtes",
+                    "type": "github"
+                },
+                {
+                    "url": "https://github.com/phpstan",
+                    "type": "github"
+                },
+                {
+                    "url": "https://www.patreon.com/phpstan",
+                    "type": "patreon"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-07-20T09:57:31+00:00"
+        },
+        {
+            "name": "phpstan/phpstan-mockery",
+            "version": "1.1.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpstan-mockery.git",
+                "reference": "245b17ccd00f04be3c6b9fc6645f63793b37b2ea"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpstan-mockery/zipball/245b17ccd00f04be3c6b9fc6645f63793b37b2ea",
+                "reference": "245b17ccd00f04be3c6b9fc6645f63793b37b2ea",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0",
+                "phpstan/phpstan": "^1.5.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.2.4",
+                "nikic/php-parser": "^4.13.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpstan/phpstan-strict-rules": "^1.0",
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "phpstan-extension",
+            "extra": {
+                "phpstan": {
+                    "includes": [
+                        "extension.neon"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PHPStan\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPStan Mockery extension",
+            "support": {
+                "issues": "https://github.com/phpstan/phpstan-mockery/issues",
+                "source": "https://github.com/phpstan/phpstan-mockery/tree/1.1.0"
+            },
+            "time": "2022-05-09T13:12:35+00:00"
+        },
+        {
+            "name": "phpstan/phpstan-webmozart-assert",
+            "version": "1.2.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/phpstan/phpstan-webmozart-assert.git",
+                "reference": "a7f12958f0c5e1f948df99a84aa03fa8df544992"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/phpstan/phpstan-webmozart-assert/zipball/a7f12958f0c5e1f948df99a84aa03fa8df544992",
+                "reference": "a7f12958f0c5e1f948df99a84aa03fa8df544992",
+                "shasum": ""
+            },
+            "require": {
+                "php": "^7.2 || ^8.0",
+                "phpstan/phpstan": "^1.6.4"
+            },
+            "require-dev": {
+                "nikic/php-parser": "^4.13.0",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/phpstan-phpunit": "^1.0",
+                "phpstan/phpstan-strict-rules": "^1.0",
+                "phpunit/phpunit": "^9.5",
+                "webmozart/assert": "^1.11.0"
+            },
+            "type": "phpstan-extension",
+            "extra": {
+                "phpstan": {
+                    "includes": [
+                        "extension.neon"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "PHPStan\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "description": "PHPStan webmozart/assert extension",
+            "support": {
+                "issues": "https://github.com/phpstan/phpstan-webmozart-assert/issues",
+                "source": "https://github.com/phpstan/phpstan-webmozart-assert/tree/1.2.0"
+            },
+            "time": "2022-06-06T08:42:28+00:00"
+        },
+        {
+            "name": "phpunit/php-code-coverage",
+            "version": "9.2.16",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+                "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073",
+                "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-libxml": "*",
+                "ext-xmlwriter": "*",
+                "nikic/php-parser": "^4.14",
+                "php": ">=7.3",
+                "phpunit/php-file-iterator": "^3.0.3",
+                "phpunit/php-text-template": "^2.0.2",
+                "sebastian/code-unit-reverse-lookup": "^2.0.2",
+                "sebastian/complexity": "^2.0",
+                "sebastian/environment": "^5.1.2",
+                "sebastian/lines-of-code": "^1.0.3",
+                "sebastian/version": "^3.0.1",
+                "theseer/tokenizer": "^1.2.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "suggest": {
+                "ext-pcov": "*",
+                "ext-xdebug": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "9.2-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
+            "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
+            "keywords": [
+                "coverage",
+                "testing",
+                "xunit"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-08-20T05:26:47+00:00"
+        },
+        {
+            "name": "phpunit/php-file-iterator",
+            "version": "3.0.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
+                "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+                "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "FilterIterator implementation that filters files based on a list of suffixes.",
+            "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
+            "keywords": [
+                "filesystem",
+                "iterator"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+                "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-12-02T12:48:52+00:00"
+        },
+        {
+            "name": "phpunit/php-invoker",
+            "version": "3.1.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-invoker.git",
+                "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+                "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "ext-pcntl": "*",
+                "phpunit/phpunit": "^9.3"
+            },
+            "suggest": {
+                "ext-pcntl": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Invoke callables with a timeout",
+            "homepage": "https://github.com/sebastianbergmann/php-invoker/",
+            "keywords": [
+                "process"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/php-invoker/issues",
+                "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-28T05:58:55+00:00"
+        },
+        {
+            "name": "phpunit/php-text-template",
+            "version": "2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-text-template.git",
+                "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+                "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Simple template engine.",
+            "homepage": "https://github.com/sebastianbergmann/php-text-template/",
+            "keywords": [
+                "template"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+                "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T05:33:50+00:00"
+        },
+        {
+            "name": "phpunit/php-timer",
+            "version": "5.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/php-timer.git",
+                "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+                "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Utility class for timing",
+            "homepage": "https://github.com/sebastianbergmann/php-timer/",
+            "keywords": [
+                "timer"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+                "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:16:10+00:00"
+        },
+        {
+            "name": "phpunit/phpunit",
+            "version": "9.5.23",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/phpunit.git",
+                "reference": "888556852e7e9bbeeedb9656afe46118765ade34"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34",
+                "reference": "888556852e7e9bbeeedb9656afe46118765ade34",
+                "shasum": ""
+            },
+            "require": {
+                "doctrine/instantiator": "^1.3.1",
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-xml": "*",
+                "ext-xmlwriter": "*",
+                "myclabs/deep-copy": "^1.10.1",
+                "phar-io/manifest": "^2.0.3",
+                "phar-io/version": "^3.0.2",
+                "php": ">=7.3",
+                "phpunit/php-code-coverage": "^9.2.13",
+                "phpunit/php-file-iterator": "^3.0.5",
+                "phpunit/php-invoker": "^3.1.1",
+                "phpunit/php-text-template": "^2.0.3",
+                "phpunit/php-timer": "^5.0.2",
+                "sebastian/cli-parser": "^1.0.1",
+                "sebastian/code-unit": "^1.0.6",
+                "sebastian/comparator": "^4.0.5",
+                "sebastian/diff": "^4.0.3",
+                "sebastian/environment": "^5.1.3",
+                "sebastian/exporter": "^4.0.3",
+                "sebastian/global-state": "^5.0.1",
+                "sebastian/object-enumerator": "^4.0.3",
+                "sebastian/resource-operations": "^3.0.3",
+                "sebastian/type": "^3.0",
+                "sebastian/version": "^3.0.2"
+            },
+            "suggest": {
+                "ext-soap": "*",
+                "ext-xdebug": "*"
+            },
+            "bin": [
+                "phpunit"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "9.5-dev"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "src/Framework/Assert/Functions.php"
+                ],
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "The PHP Unit Testing framework.",
+            "homepage": "https://phpunit.de/",
+            "keywords": [
+                "phpunit",
+                "testing",
+                "xunit"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+                "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23"
+            },
+            "funding": [
+                {
+                    "url": "https://phpunit.de/sponsors.html",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-08-22T14:01:36+00:00"
+        },
+        {
+            "name": "psr/container",
+            "version": "1.1.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/container.git",
+                "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
+                "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.4.0"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Container\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common Container Interface (PHP FIG PSR-11)",
+            "homepage": "https://github.com/php-fig/container",
+            "keywords": [
+                "PSR-11",
+                "container",
+                "container-interface",
+                "container-interop",
+                "psr"
+            ],
+            "support": {
+                "issues": "https://github.com/php-fig/container/issues",
+                "source": "https://github.com/php-fig/container/tree/1.1.2"
+            },
+            "time": "2021-11-05T16:50:12+00:00"
+        },
+        {
+            "name": "psr/log",
+            "version": "1.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/php-fig/log.git",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11",
+                "reference": "d49695b909c3b7628b6289db5479a1c204601f11",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psr\\Log\\": "Psr/Log/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "PHP-FIG",
+                    "homepage": "https://www.php-fig.org/"
+                }
+            ],
+            "description": "Common interface for logging libraries",
+            "homepage": "https://github.com/php-fig/log",
+            "keywords": [
+                "log",
+                "psr",
+                "psr-3"
+            ],
+            "support": {
+                "source": "https://github.com/php-fig/log/tree/1.1.4"
+            },
+            "time": "2021-05-03T11:20:27+00:00"
+        },
+        {
+            "name": "sebastian/cli-parser",
+            "version": "1.0.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/cli-parser.git",
+                "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+                "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library for parsing CLI options",
+            "homepage": "https://github.com/sebastianbergmann/cli-parser",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/cli-parser/issues",
+                "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-28T06:08:49+00:00"
+        },
+        {
+            "name": "sebastian/code-unit",
+            "version": "1.0.8",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit.git",
+                "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120",
+                "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Collection of value objects that represent the PHP code units",
+            "homepage": "https://github.com/sebastianbergmann/code-unit",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/code-unit/issues",
+                "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:08:54+00:00"
+        },
+        {
+            "name": "sebastian/code-unit-reverse-lookup",
+            "version": "2.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
+                "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+                "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Looks up which function or method a line of code belongs to",
+            "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+                "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-28T05:30:19+00:00"
+        },
+        {
+            "name": "sebastian/comparator",
+            "version": "4.0.6",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/comparator.git",
+                "reference": "55f4261989e546dc112258c7a75935a81a7ce382"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382",
+                "reference": "55f4261989e546dc112258c7a75935a81a7ce382",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3",
+                "sebastian/diff": "^4.0",
+                "sebastian/exporter": "^4.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@2bepublished.at"
+                }
+            ],
+            "description": "Provides the functionality to compare PHP values for equality",
+            "homepage": "https://github.com/sebastianbergmann/comparator",
+            "keywords": [
+                "comparator",
+                "compare",
+                "equality"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/comparator/issues",
+                "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T15:49:45+00:00"
+        },
+        {
+            "name": "sebastian/complexity",
+            "version": "2.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/complexity.git",
+                "reference": "739b35e53379900cc9ac327b2147867b8b6efd88"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88",
+                "reference": "739b35e53379900cc9ac327b2147867b8b6efd88",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^4.7",
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library for calculating the complexity of PHP code units",
+            "homepage": "https://github.com/sebastianbergmann/complexity",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/complexity/issues",
+                "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T15:52:27+00:00"
+        },
+        {
+            "name": "sebastian/diff",
+            "version": "4.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/diff.git",
+                "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+                "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3",
+                "symfony/process": "^4.2 || ^5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Kore Nordmann",
+                    "email": "mail@kore-nordmann.de"
+                }
+            ],
+            "description": "Diff implementation",
+            "homepage": "https://github.com/sebastianbergmann/diff",
+            "keywords": [
+                "diff",
+                "udiff",
+                "unidiff",
+                "unified diff"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/diff/issues",
+                "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:10:38+00:00"
+        },
+        {
+            "name": "sebastian/environment",
+            "version": "5.1.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/environment.git",
+                "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7",
+                "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "suggest": {
+                "ext-posix": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.1-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides functionality to handle HHVM/PHP environments",
+            "homepage": "http://www.github.com/sebastianbergmann/environment",
+            "keywords": [
+                "Xdebug",
+                "environment",
+                "hhvm"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/environment/issues",
+                "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-04-03T09:37:03+00:00"
+        },
+        {
+            "name": "sebastian/exporter",
+            "version": "4.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/exporter.git",
+                "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9",
+                "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3",
+                "sebastian/recursion-context": "^4.0"
+            },
+            "require-dev": {
+                "ext-mbstring": "*",
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Volker Dusch",
+                    "email": "github@wallbash.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                },
+                {
+                    "name": "Bernhard Schussek",
+                    "email": "bschussek@gmail.com"
+                }
+            ],
+            "description": "Provides the functionality to export PHP variables for visualization",
+            "homepage": "https://www.github.com/sebastianbergmann/exporter",
+            "keywords": [
+                "export",
+                "exporter"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/exporter/issues",
+                "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-11-11T14:18:36+00:00"
+        },
+        {
+            "name": "sebastian/global-state",
+            "version": "5.0.5",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/global-state.git",
+                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+                "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3",
+                "sebastian/object-reflector": "^2.0",
+                "sebastian/recursion-context": "^4.0"
+            },
+            "require-dev": {
+                "ext-dom": "*",
+                "phpunit/phpunit": "^9.3"
+            },
+            "suggest": {
+                "ext-uopz": "*"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Snapshotting of global state",
+            "homepage": "http://www.github.com/sebastianbergmann/global-state",
+            "keywords": [
+                "global state"
+            ],
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/global-state/issues",
+                "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-02-14T08:28:10+00:00"
+        },
+        {
+            "name": "sebastian/lines-of-code",
+            "version": "1.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/lines-of-code.git",
+                "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+                "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc",
+                "shasum": ""
+            },
+            "require": {
+                "nikic/php-parser": "^4.6",
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "1.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library for counting the lines of code in PHP source code",
+            "homepage": "https://github.com/sebastianbergmann/lines-of-code",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/lines-of-code/issues",
+                "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-11-28T06:42:11+00:00"
+        },
+        {
+            "name": "sebastian/object-enumerator",
+            "version": "4.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-enumerator.git",
+                "reference": "5c9eeac41b290a3712d88851518825ad78f45c71"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71",
+                "reference": "5c9eeac41b290a3712d88851518825ad78f45c71",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3",
+                "sebastian/object-reflector": "^2.0",
+                "sebastian/recursion-context": "^4.0"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Traverses array structures and object graphs to enumerate all referenced objects",
+            "homepage": "https://github.com/sebastianbergmann/object-enumerator/",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+                "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:12:34+00:00"
+        },
+        {
+            "name": "sebastian/object-reflector",
+            "version": "2.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/object-reflector.git",
+                "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+                "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "2.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Allows reflection of object attributes, including inherited and non-public ones",
+            "homepage": "https://github.com/sebastianbergmann/object-reflector/",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+                "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:14:26+00:00"
+        },
+        {
+            "name": "sebastian/recursion-context",
+            "version": "4.0.4",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/recursion-context.git",
+                "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172",
+                "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "4.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                },
+                {
+                    "name": "Jeff Welch",
+                    "email": "whatthejeff@gmail.com"
+                },
+                {
+                    "name": "Adam Harvey",
+                    "email": "aharvey@php.net"
+                }
+            ],
+            "description": "Provides functionality to recursively process PHP variables",
+            "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+                "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-10-26T13:17:30+00:00"
+        },
+        {
+            "name": "sebastian/resource-operations",
+            "version": "3.0.3",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/resource-operations.git",
+                "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+                "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.0"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de"
+                }
+            ],
+            "description": "Provides a list of PHP built-in functions that operate on resources",
+            "homepage": "https://www.github.com/sebastianbergmann/resource-operations",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+                "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-28T06:45:17+00:00"
+        },
+        {
+            "name": "sebastian/type",
+            "version": "3.0.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/type.git",
+                "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
+                "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "require-dev": {
+                "phpunit/phpunit": "^9.5"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Collection of value objects that represent the types of the PHP type system",
+            "homepage": "https://github.com/sebastianbergmann/type",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/type/issues",
+                "source": "https://github.com/sebastianbergmann/type/tree/3.0.0"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-03-15T09:54:48+00:00"
+        },
+        {
+            "name": "sebastian/version",
+            "version": "3.0.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/sebastianbergmann/version.git",
+                "reference": "c6c1022351a901512170118436c764e473f6de8c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c",
+                "reference": "c6c1022351a901512170118436c764e473f6de8c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.3"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "3.0-dev"
+                }
+            },
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Sebastian Bergmann",
+                    "email": "sebastian@phpunit.de",
+                    "role": "lead"
+                }
+            ],
+            "description": "Library that helps with managing the version number of Git-hosted PHP projects",
+            "homepage": "https://github.com/sebastianbergmann/version",
+            "support": {
+                "issues": "https://github.com/sebastianbergmann/version/issues",
+                "source": "https://github.com/sebastianbergmann/version/tree/3.0.2"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/sebastianbergmann",
+                    "type": "github"
+                }
+            ],
+            "time": "2020-09-28T06:39:44+00:00"
+        },
+        {
+            "name": "spatie/array-to-xml",
+            "version": "2.17.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/spatie/array-to-xml.git",
+                "reference": "5cbec9c6ab17e320c58a259f0cebe88bde4a7c46"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/spatie/array-to-xml/zipball/5cbec9c6ab17e320c58a259f0cebe88bde4a7c46",
+                "reference": "5cbec9c6ab17e320c58a259f0cebe88bde4a7c46",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "php": "^7.4|^8.0"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.2",
+                "pestphp/pest": "^1.21",
+                "phpunit/phpunit": "^9.0",
+                "spatie/pest-plugin-snapshots": "^1.1"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Spatie\\ArrayToXml\\": "src"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Freek Van der Herten",
+                    "email": "freek@spatie.be",
+                    "homepage": "https://freek.dev",
+                    "role": "Developer"
+                }
+            ],
+            "description": "Convert an array to xml",
+            "homepage": "https://github.com/spatie/array-to-xml",
+            "keywords": [
+                "array",
+                "convert",
+                "xml"
+            ],
+            "support": {
+                "source": "https://github.com/spatie/array-to-xml/tree/2.17.1"
+            },
+            "funding": [
+                {
+                    "url": "https://spatie.be/open-source/support-us",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/spatie",
+                    "type": "github"
+                }
+            ],
+            "time": "2022-12-26T08:22:07+00:00"
+        },
+        {
+            "name": "symfony/console",
+            "version": "v5.4.12",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/console.git",
+                "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1",
+                "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/deprecation-contracts": "^2.1|^3",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php73": "^1.9",
+                "symfony/polyfill-php80": "^1.16",
+                "symfony/service-contracts": "^1.1|^2|^3",
+                "symfony/string": "^5.1|^6.0"
+            },
+            "conflict": {
+                "psr/log": ">=3",
+                "symfony/dependency-injection": "<4.4",
+                "symfony/dotenv": "<5.1",
+                "symfony/event-dispatcher": "<4.4",
+                "symfony/lock": "<4.4",
+                "symfony/process": "<4.4"
+            },
+            "provide": {
+                "psr/log-implementation": "1.0|2.0"
+            },
+            "require-dev": {
+                "psr/log": "^1|^2",
+                "symfony/config": "^4.4|^5.0|^6.0",
+                "symfony/dependency-injection": "^4.4|^5.0|^6.0",
+                "symfony/event-dispatcher": "^4.4|^5.0|^6.0",
+                "symfony/lock": "^4.4|^5.0|^6.0",
+                "symfony/process": "^4.4|^5.0|^6.0",
+                "symfony/var-dumper": "^4.4|^5.0|^6.0"
+            },
+            "suggest": {
+                "psr/log": "For using the console logger",
+                "symfony/event-dispatcher": "",
+                "symfony/lock": "",
+                "symfony/process": ""
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Console\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Eases the creation of beautiful and testable command line interfaces",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "cli",
+                "command line",
+                "console",
+                "terminal"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/console/tree/v5.4.12"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-08-17T13:18:05+00:00"
+        },
+        {
+            "name": "symfony/deprecation-contracts",
+            "version": "v2.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/deprecation-contracts.git",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "function.php"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "A generic function and convention to trigger deprecation notices",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-01-02T09:53:40+00:00"
+        },
+        {
+            "name": "symfony/filesystem",
+            "version": "v5.4.35",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/filesystem.git",
+                "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/filesystem/zipball/5a553607d4ffbfa9c0ab62facadea296c9db7086",
+                "reference": "5a553607d4ffbfa9c0ab62facadea296c9db7086",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-mbstring": "~1.8",
+                "symfony/polyfill-php80": "^1.16"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Component\\Filesystem\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Fabien Potencier",
+                    "email": "fabien@symfony.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides basic utilities for the filesystem",
+            "homepage": "https://symfony.com",
+            "support": {
+                "source": "https://github.com/symfony/filesystem/tree/v5.4.35"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2024-01-23T13:51:25+00:00"
+        },
+        {
+            "name": "symfony/polyfill-ctype",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-ctype.git",
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+                "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-ctype": "*"
+            },
+            "suggest": {
+                "ext-ctype": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Ctype\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Gert de Pagter",
+                    "email": "BackEndTea@gmail.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for ctype functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "ctype",
+                "polyfill",
+                "portable"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-24T11:49:31+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-grapheme",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-grapheme.git",
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2",
+                "reference": "433d05519ce6990bf3530fba6957499d327395c2",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Grapheme\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's grapheme_* functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "grapheme",
+                "intl",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-24T11:49:31+00:00"
+        },
+        {
+            "name": "symfony/polyfill-intl-normalizer",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-intl-normalizer.git",
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd",
+                "reference": "219aa369ceff116e673852dce47c3a41794c14bd",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "suggest": {
+                "ext-intl": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Intl\\Normalizer\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for intl's Normalizer class and related functions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "intl",
+                "normalizer",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-24T11:49:31+00:00"
+        },
+        {
+            "name": "symfony/polyfill-mbstring",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-mbstring.git",
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+                "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "provide": {
+                "ext-mbstring": "*"
+            },
+            "suggest": {
+                "ext-mbstring": "For best performance"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Mbstring\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill for the Mbstring extension",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "mbstring",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-24T11:49:31+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php73",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php73.git",
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85",
+                "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php73\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-24T11:49:31+00:00"
+        },
+        {
+            "name": "symfony/polyfill-php80",
+            "version": "v1.26.0",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/polyfill-php80.git",
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+                "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.1"
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "1.26-dev"
+                },
+                "thanks": {
+                    "name": "symfony/polyfill",
+                    "url": "https://github.com/symfony/polyfill"
+                }
+            },
+            "autoload": {
+                "files": [
+                    "bootstrap.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Polyfill\\Php80\\": ""
+                },
+                "classmap": [
+                    "Resources/stubs"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Ion Bazan",
+                    "email": "ion.bazan@gmail.com"
+                },
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "compatibility",
+                "polyfill",
+                "portable",
+                "shim"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-10T07:21:04+00:00"
+        },
+        {
+            "name": "symfony/service-contracts",
+            "version": "v2.5.2",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/service-contracts.git",
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+                "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "psr/container": "^1.1",
+                "symfony/deprecation-contracts": "^2.1|^3"
+            },
+            "conflict": {
+                "ext-psr": "<1.1|>=2"
+            },
+            "suggest": {
+                "symfony/service-implementation": ""
+            },
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-main": "2.5-dev"
+                },
+                "thanks": {
+                    "name": "symfony/contracts",
+                    "url": "https://github.com/symfony/contracts"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Symfony\\Contracts\\Service\\": ""
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Generic abstractions related to writing services",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "abstractions",
+                "contracts",
+                "decoupling",
+                "interfaces",
+                "interoperability",
+                "standards"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/service-contracts/tree/v2.5.2"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-05-30T19:17:29+00:00"
+        },
+        {
+            "name": "symfony/string",
+            "version": "v5.4.12",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/symfony/string.git",
+                "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058",
+                "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=7.2.5",
+                "symfony/polyfill-ctype": "~1.8",
+                "symfony/polyfill-intl-grapheme": "~1.0",
+                "symfony/polyfill-intl-normalizer": "~1.0",
+                "symfony/polyfill-mbstring": "~1.0",
+                "symfony/polyfill-php80": "~1.15"
+            },
+            "conflict": {
+                "symfony/translation-contracts": ">=3.0"
+            },
+            "require-dev": {
+                "symfony/error-handler": "^4.4|^5.0|^6.0",
+                "symfony/http-client": "^4.4|^5.0|^6.0",
+                "symfony/translation-contracts": "^1.1|^2",
+                "symfony/var-exporter": "^4.4|^5.0|^6.0"
+            },
+            "type": "library",
+            "autoload": {
+                "files": [
+                    "Resources/functions.php"
+                ],
+                "psr-4": {
+                    "Symfony\\Component\\String\\": ""
+                },
+                "exclude-from-classmap": [
+                    "/Tests/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Nicolas Grekas",
+                    "email": "p@tchwork.com"
+                },
+                {
+                    "name": "Symfony Community",
+                    "homepage": "https://symfony.com/contributors"
+                }
+            ],
+            "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
+            "homepage": "https://symfony.com",
+            "keywords": [
+                "grapheme",
+                "i18n",
+                "string",
+                "unicode",
+                "utf-8",
+                "utf8"
+            ],
+            "support": {
+                "source": "https://github.com/symfony/string/tree/v5.4.12"
+            },
+            "funding": [
+                {
+                    "url": "https://symfony.com/sponsor",
+                    "type": "custom"
+                },
+                {
+                    "url": "https://github.com/fabpot",
+                    "type": "github"
+                },
+                {
+                    "url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
+                    "type": "tidelift"
+                }
+            ],
+            "time": "2022-08-12T17:03:11+00:00"
+        },
+        {
+            "name": "theseer/tokenizer",
+            "version": "1.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/theseer/tokenizer.git",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e",
+                "shasum": ""
+            },
+            "require": {
+                "ext-dom": "*",
+                "ext-tokenizer": "*",
+                "ext-xmlwriter": "*",
+                "php": "^7.2 || ^8.0"
+            },
+            "type": "library",
+            "autoload": {
+                "classmap": [
+                    "src/"
+                ]
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "BSD-3-Clause"
+            ],
+            "authors": [
+                {
+                    "name": "Arne Blankerts",
+                    "email": "arne@blankerts.de",
+                    "role": "Developer"
+                }
+            ],
+            "description": "A small library for converting tokenized PHP source code into XML and potentially other formats",
+            "support": {
+                "issues": "https://github.com/theseer/tokenizer/issues",
+                "source": "https://github.com/theseer/tokenizer/tree/1.2.1"
+            },
+            "funding": [
+                {
+                    "url": "https://github.com/theseer",
+                    "type": "github"
+                }
+            ],
+            "time": "2021-07-28T10:34:58+00:00"
+        },
+        {
+            "name": "vimeo/psalm",
+            "version": "5.13.1",
+            "source": {
+                "type": "git",
+                "url": "https://github.com/vimeo/psalm.git",
+                "reference": "086b94371304750d1c673315321a55d15fc59015"
+            },
+            "dist": {
+                "type": "zip",
+                "url": "https://api.github.com/repos/vimeo/psalm/zipball/086b94371304750d1c673315321a55d15fc59015",
+                "reference": "086b94371304750d1c673315321a55d15fc59015",
+                "shasum": ""
+            },
+            "require": {
+                "amphp/amp": "^2.4.2",
+                "amphp/byte-stream": "^1.5",
+                "composer-runtime-api": "^2",
+                "composer/semver": "^1.4 || ^2.0 || ^3.0",
+                "composer/xdebug-handler": "^2.0 || ^3.0",
+                "dnoegel/php-xdg-base-dir": "^0.1.1",
+                "ext-ctype": "*",
+                "ext-dom": "*",
+                "ext-json": "*",
+                "ext-libxml": "*",
+                "ext-mbstring": "*",
+                "ext-simplexml": "*",
+                "ext-tokenizer": "*",
+                "felixfbecker/advanced-json-rpc": "^3.1",
+                "felixfbecker/language-server-protocol": "^1.5.2",
+                "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1",
+                "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0",
+                "nikic/php-parser": "^4.14",
+                "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0",
+                "sebastian/diff": "^4.0 || ^5.0",
+                "spatie/array-to-xml": "^2.17.0 || ^3.0",
+                "symfony/console": "^4.1.6 || ^5.0 || ^6.0",
+                "symfony/filesystem": "^5.4 || ^6.0"
+            },
+            "provide": {
+                "psalm/psalm": "self.version"
+            },
+            "require-dev": {
+                "amphp/phpunit-util": "^2.0",
+                "bamarni/composer-bin-plugin": "^1.4",
+                "brianium/paratest": "^6.9",
+                "ext-curl": "*",
+                "mockery/mockery": "^1.5",
+                "nunomaduro/mock-final-classes": "^1.1",
+                "php-parallel-lint/php-parallel-lint": "^1.2",
+                "phpstan/phpdoc-parser": "^1.6",
+                "phpunit/phpunit": "^9.6",
+                "psalm/plugin-mockery": "^1.1",
+                "psalm/plugin-phpunit": "^0.18",
+                "slevomat/coding-standard": "^8.4",
+                "squizlabs/php_codesniffer": "^3.6",
+                "symfony/process": "^4.4 || ^5.0 || ^6.0"
+            },
+            "suggest": {
+                "ext-curl": "In order to send data to shepherd",
+                "ext-igbinary": "^2.0.5 is required, used to serialize caching data"
+            },
+            "bin": [
+                "psalm",
+                "psalm-language-server",
+                "psalm-plugin",
+                "psalm-refactor",
+                "psalter"
+            ],
+            "type": "library",
+            "extra": {
+                "branch-alias": {
+                    "dev-master": "5.x-dev",
+                    "dev-4.x": "4.x-dev",
+                    "dev-3.x": "3.x-dev",
+                    "dev-2.x": "2.x-dev",
+                    "dev-1.x": "1.x-dev"
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Psalm\\": "src/Psalm/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Matthew Brown"
+                }
+            ],
+            "description": "A static analysis tool for finding errors in PHP applications",
+            "keywords": [
+                "code",
+                "inspection",
+                "php",
+                "static analysis"
+            ],
+            "support": {
+                "issues": "https://github.com/vimeo/psalm/issues",
+                "source": "https://github.com/vimeo/psalm/tree/5.13.1"
+            },
+            "time": "2023-06-27T16:39:49+00:00"
+        }
+    ],
+    "aliases": [],
+    "minimum-stability": "stable",
+    "stability-flags": [],
+    "prefer-stable": false,
+    "prefer-lowest": false,
+    "platform": {
+        "php": "^7.4 || ^8.0",
+        "ext-filter": "*"
+    },
+    "platform-dev": [],
+    "platform-overrides": {
+        "php": "7.4.0"
+    },
+    "plugin-api-version": "2.6.0"
 }
diff --git a/examples/04-adding-your-own-tag.php b/examples/04-adding-your-own-tag.php
index 49f751d99eacf4e5a640aa0580edb2082a2b7588..38ab724831c44aaa144099fa015f0635c2c272e3 100644
--- a/examples/04-adding-your-own-tag.php
+++ b/examples/04-adding-your-own-tag.php
@@ -42,7 +42,7 @@ final class MyTag extends BaseTag
      *
      * @var string
      */
-    protected $name = 'my-tag';
+    protected string $name = 'my-tag';
 
     /**
      * The constructor for this Tag; this should contain all properties for this object.
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 27aa317bf984592cb0d94b9bbc8952eeda36596a..03c8954182965db9d31551377a9bab6131295b4a 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -10,13 +10,10 @@
 
     <!-- Set the minimum PHP version for PHPCompatibility.
          This should be kept in sync with the requirements in the composer.json file. -->
-    <config name="testVersion" value="7.2-"/>
+    <config name="testVersion" value="7.4-"/>
 
     <rule ref="phpDocumentor">
         <exclude name="SlevomatCodingStandard.Exceptions.ReferenceThrowableOnly.ReferencedGeneralException" />
-
-        <!-- Property type declarations are a PHP 7.4 feature. -->
-        <exclude name="SlevomatCodingStandard.TypeHints.PropertyTypeHint.MissingNativeTypeHint"/>
     </rule>
 
     <rule ref="SlevomatCodingStandard.Classes.SuperfluousAbstractClassNaming.SuperfluousPrefix">
diff --git a/phpstan.neon b/phpstan.neon
index b215c6a944e9b0929b5b675fa7646d86b2065a53..bd23f0af153ccaee39fa4da3d92d68fd12bf1a83 100644
--- a/phpstan.neon
+++ b/phpstan.neon
@@ -1,8 +1,8 @@
-includes:
-    - /composer/vendor/phpstan/phpstan-mockery/extension.neon
-    - /composer/vendor/phpstan/phpstan-webmozart-assert/extension.neon
-
 parameters:
     level: max
     ignoreErrors:
-        - '#Call to static method Webmozart\\Assert\\Assert::implementsInterface\(\) with class-string#'
\ No newline at end of file
+        - '#Method phpDocumentor\\Reflection\\DocBlock\\StandardTagFactory::createTag\(\) should return phpDocumentor\\Reflection\\DocBlock\\Tag but returns mixed#'
+        - "#Strict comparison using !== between array{'name', 'type'} and array{'name', 'type'} will always evaluate to false#"
+        - '#Call to static method Webmozart\\Assert\\Assert::implementsInterface\(\) with class-string#'
+    paths:
+        - src
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index fd7ab7487b8b9221e1250bf2ff6b0ae7756603e5..baf0ad6351f251cc3ee35a3afac8260a0446215f 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -4,8 +4,8 @@
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/8.0/phpunit.xsd"
         colors="true"
-        convertDeprecationsToExceptions="true"
-        beStrictAboutOutputDuringTests="true"
+        convertDeprecationsToExceptions="false"
+        beStrictAboutOutputDuringTests="false"
         forceCoversAnnotation="true"
         verbose="true"
         bootstrap="vendor/autoload.php"
diff --git a/psalm.xml b/psalm.xml
index 16f283f8d6269bd3ab9f30ee27e152a7065de8dd..7f491f7f233a6ea1d112e6313c994d9e381f2e1b 100644
--- a/psalm.xml
+++ b/psalm.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0"?>
 <psalm
-    totallyTyped="false"
+    errorLevel="2"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xmlns="https://getpsalm.org/schema/config"
     xsi:schemaLocation="https://getpsalm.org/schema/config file:///composer/vendor/vimeo/psalm/config.xsd"
@@ -34,6 +34,19 @@
             </errorLevel>
         </DeprecatedInterface>
 
+        <DeprecatedMethod>
+            <errorLevel type="info">
+                <!-- Will be removed in 6.0.0 issues/361 -->
+                <referencedMethod name="phpDocumentor\Reflection\DocBlock\Tags\Param::create"/>
+            </errorLevel>
+        </DeprecatedMethod>
+
+        <NoInterfaceProperties>
+            <errorLevel type="info">
+                <file name="src/DocBlock/Tags/Factory/ParamFactory.php"/>
+            </errorLevel>
+        </NoInterfaceProperties>
+
         <RedundantConditionGivenDocblockType>
             <errorLevel type="info">
                 <!-- Psalm manage to infer a more precise type than PHPStan. notNull assert is needed for PHPStan but
diff --git a/src/DocBlock.php b/src/DocBlock.php
index cc33e60e6e8ee7c8df9300c0ad1cd6522af03fd4..90d8066d5fed662d7d3dffb1366126e5d746ad06 100644
--- a/src/DocBlock.php
+++ b/src/DocBlock.php
@@ -20,25 +20,25 @@ use Webmozart\Assert\Assert;
 final class DocBlock
 {
     /** @var string The opening line for this docblock. */
-    private $summary;
+    private string $summary;
 
     /** @var DocBlock\Description The actual description for this docblock. */
-    private $description;
+    private DocBlock\Description $description;
 
     /** @var Tag[] An array containing all the tags in this docblock; except inline. */
-    private $tags = [];
+    private array $tags = [];
 
     /** @var Types\Context|null Information about the context of this DocBlock. */
-    private $context;
+    private ?Types\Context $context = null;
 
     /** @var Location|null Information about the location of this DocBlock. */
-    private $location;
+    private ?Location $location = null;
 
     /** @var bool Is this DocBlock (the start of) a template? */
-    private $isTemplateStart;
+    private bool $isTemplateStart;
 
     /** @var bool Does this DocBlock signify the end of a DocBlock template? */
-    private $isTemplateEnd;
+    private bool $isTemplateEnd;
 
     /**
      * @param DocBlock\Tag[] $tags
diff --git a/src/DocBlock/Description.php b/src/DocBlock/Description.php
index a31b2892a3530c42904d11a67d9f4e6447cd00ed..a188ae30f3ab6cf66b8f80e07ecc2c4bbee2ab3a 100644
--- a/src/DocBlock/Description.php
+++ b/src/DocBlock/Description.php
@@ -48,15 +48,14 @@ use function vsprintf;
  * is mainly responsible for rendering.
  *
  * @see DescriptionFactory to create a new Description.
- * @see Description\Formatter for the formatting of the body and tags.
+ * @see Tags\Formatter for the formatting of the body and tags.
  */
 class Description
 {
-    /** @var string */
-    private $bodyTemplate;
+    private string $bodyTemplate;
 
     /** @var Tag[] */
-    private $tags;
+    private array $tags;
 
     /**
      * Initializes a Description with its body (template) and a listing of the tags used in the body template.
@@ -93,6 +92,10 @@ class Description
      */
     public function render(?Formatter $formatter = null): string
     {
+        if ($this->tags === []) {
+            return vsprintf($this->bodyTemplate, []);
+        }
+
         if ($formatter === null) {
             $formatter = new PassthroughFormatter();
         }
diff --git a/src/DocBlock/DescriptionFactory.php b/src/DocBlock/DescriptionFactory.php
index 1a519ec4a4413e7b219b1a6b9d02811ebdea776a..e7bc616d18b84beb100b6364a35a3c6ab5718041 100644
--- a/src/DocBlock/DescriptionFactory.php
+++ b/src/DocBlock/DescriptionFactory.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock;
 
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
 use phpDocumentor\Reflection\Types\Context as TypeContext;
 use phpDocumentor\Reflection\Utils;
 
@@ -47,13 +48,12 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 class DescriptionFactory
 {
-    /** @var TagFactory */
-    private $tagFactory;
+    private Factory $tagFactory;
 
     /**
      * Initializes this factory with the means to construct (inline) tags.
      */
-    public function __construct(TagFactory $tagFactory)
+    public function __construct(Factory $tagFactory)
     {
         $this->tagFactory = $tagFactory;
     }
diff --git a/src/DocBlock/ExampleFinder.php b/src/DocBlock/ExampleFinder.php
index 6a6b47295e801c66a5f29d7249a03fc34477e773..7136e28f4ef3bd5b0f6d3493c683c1609ac57971 100644
--- a/src/DocBlock/ExampleFinder.php
+++ b/src/DocBlock/ExampleFinder.php
@@ -31,11 +31,10 @@ use const DIRECTORY_SEPARATOR;
  */
 class ExampleFinder
 {
-    /** @var string */
-    private $sourceDirectory = '';
+    private string $sourceDirectory = '';
 
     /** @var string[] */
-    private $exampleDirectories = [];
+    private array $exampleDirectories = [];
 
     /**
      * Attempts to find the example contents for the given descriptor.
diff --git a/src/DocBlock/Serializer.php b/src/DocBlock/Serializer.php
index 77e5fb5fa51f90212152904d2041f0e0cf074661..31ca29c50d6e4271a1a3afe504b879dbefdef0e4 100644
--- a/src/DocBlock/Serializer.php
+++ b/src/DocBlock/Serializer.php
@@ -29,21 +29,20 @@ use function wordwrap;
 class Serializer
 {
     /** @var string The string to indent the comment with. */
-    protected $indentString = ' ';
+    protected string $indentString = ' ';
 
     /** @var int The number of times the indent string is repeated. */
-    protected $indent = 0;
+    protected int $indent = 0;
 
     /** @var bool Whether to indent the first line with the given indent amount and string. */
-    protected $isFirstLineIndented = true;
+    protected bool $isFirstLineIndented = true;
 
     /** @var int|null The max length of a line. */
-    protected $lineLength;
+    protected ?int $lineLength = null;
 
     /** @var Formatter A custom tag formatter. */
-    protected $tagFormatter;
-    /** @var string */
-    private $lineEnding;
+    protected Formatter $tagFormatter;
+    private string $lineEnding;
 
     /**
      * Create a Serializer instance.
diff --git a/src/DocBlock/StandardTagFactory.php b/src/DocBlock/StandardTagFactory.php
index 8d765951097164f9bf8d349dfb4e711495771700..7360a707a408d69730971320ae167e86b76e6a88 100644
--- a/src/DocBlock/StandardTagFactory.php
+++ b/src/DocBlock/StandardTagFactory.php
@@ -17,6 +17,7 @@ use InvalidArgumentException;
 use phpDocumentor\Reflection\DocBlock\Tags\Author;
 use phpDocumentor\Reflection\DocBlock\Tags\Covers;
 use phpDocumentor\Reflection\DocBlock\Tags\Deprecated;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
 use phpDocumentor\Reflection\DocBlock\Tags\Generic;
 use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
 use phpDocumentor\Reflection\DocBlock\Tags\Link as LinkTag;
@@ -40,12 +41,15 @@ use ReflectionNamedType;
 use ReflectionParameter;
 use Webmozart\Assert\Assert;
 
+use function array_key_exists;
 use function array_merge;
 use function array_slice;
 use function call_user_func_array;
 use function count;
 use function get_class;
+use function is_object;
 use function preg_match;
+use function sprintf;
 use function strpos;
 use function trim;
 
@@ -72,10 +76,10 @@ final class StandardTagFactory implements TagFactory
     public const REGEX_TAGNAME = '[\w\-\_\\\\:]+';
 
     /**
-     * @var array<class-string<Tag>> An array with a tag as a key, and an
+     * @var array<class-string<Tag>|Factory> An array with a tag as a key, and an
      *                               FQCN to a class that handles it as an array value.
      */
-    private $tagHandlerMappings = [
+    private array $tagHandlerMappings = [
         'author' => Author::class,
         'covers' => Covers::class,
         'deprecated' => Deprecated::class,
@@ -101,22 +105,21 @@ final class StandardTagFactory implements TagFactory
      * @var array<class-string<Tag>> An array with a anotation s a key, and an
      *      FQCN to a class that handles it as an array value.
      */
-    private $annotationMappings = [];
+    private array $annotationMappings = [];
 
     /**
      * @var ReflectionParameter[][] a lazy-loading cache containing parameters
      *      for each tagHandler that has been used.
      */
-    private $tagHandlerParameterCache = [];
+    private array $tagHandlerParameterCache = [];
 
-    /** @var FqsenResolver */
-    private $fqsenResolver;
+    private FqsenResolver $fqsenResolver;
 
     /**
      * @var mixed[] an array representing a simple Service Locator where we can store parameters and
      *     services that can be inserted into the Factory Methods of Tag Handlers.
      */
-    private $serviceLocator = [];
+    private array $serviceLocator = [];
 
     /**
      * Initialize this tag factory with the means to resolve an FQSEN and optionally a list of tag handlers.
@@ -162,18 +165,25 @@ final class StandardTagFactory implements TagFactory
         $this->serviceLocator[$alias ?: get_class($service)] = $service;
     }
 
-    public function registerTagHandler(string $tagName, string $handler): void
+    /** {@inheritDoc} */
+    public function registerTagHandler(string $tagName, $handler): void
     {
         Assert::stringNotEmpty($tagName);
-        Assert::classExists($handler);
-        Assert::implementsInterface($handler, Tag::class);
-
         if (strpos($tagName, '\\') && $tagName[0] !== '\\') {
             throw new InvalidArgumentException(
                 'A namespaced tag must have a leading backslash as it must be fully qualified'
             );
         }
 
+        if (is_object($handler)) {
+            Assert::isInstanceOf($handler, Factory::class);
+            $this->tagHandlerMappings[$tagName] = $handler;
+
+            return;
+        }
+
+        Assert::classExists($handler);
+        Assert::implementsInterface($handler, Tag::class);
         $this->tagHandlerMappings[$tagName] = $handler;
     }
 
@@ -210,6 +220,10 @@ final class StandardTagFactory implements TagFactory
             $this->getServiceLocatorWithDynamicParameters($context, $name, $body)
         );
 
+        if (array_key_exists('tagLine', $arguments)) {
+            $arguments['tagLine'] = sprintf('@%s %s', $name, $body);
+        }
+
         try {
             $callable = [$handlerClassName, 'create'];
             Assert::isCallable($callable);
@@ -225,9 +239,9 @@ final class StandardTagFactory implements TagFactory
     /**
      * Determines the Fully Qualified Class Name of the Factory or Tag (containing a Factory Method `create`).
      *
-     * @return class-string<Tag>
+     * @return class-string<Tag>|Factory
      */
-    private function findHandlerClassName(string $tagName, TypeContext $context): string
+    private function findHandlerClassName(string $tagName, TypeContext $context)
     {
         $handlerClassName = Generic::class;
         if (isset($this->tagHandlerMappings[$tagName])) {
@@ -268,18 +282,18 @@ final class StandardTagFactory implements TagFactory
                 }
             }
 
+            $parameterName = $parameter->getName();
             if (isset($locator[$typeHint])) {
-                $arguments[] = $locator[$typeHint];
+                $arguments[$parameterName] = $locator[$typeHint];
                 continue;
             }
 
-            $parameterName = $parameter->getName();
             if (isset($locator[$parameterName])) {
-                $arguments[] = $locator[$parameterName];
+                $arguments[$parameterName] = $locator[$parameterName];
                 continue;
             }
 
-            $arguments[] = null;
+            $arguments[$parameterName] = null;
         }
 
         return $arguments;
@@ -289,12 +303,14 @@ final class StandardTagFactory implements TagFactory
      * Retrieves a series of ReflectionParameter objects for the static 'create' method of the given
      * tag handler class name.
      *
-     * @param class-string $handlerClassName
+     * @param class-string|Factory $handler
      *
      * @return ReflectionParameter[]
      */
-    private function fetchParametersForHandlerFactoryMethod(string $handlerClassName): array
+    private function fetchParametersForHandlerFactoryMethod($handler): array
     {
+        $handlerClassName = is_object($handler) ? get_class($handler) : $handler;
+
         if (!isset($this->tagHandlerParameterCache[$handlerClassName])) {
             $methodReflection                                  = new ReflectionMethod($handlerClassName, 'create');
             $this->tagHandlerParameterCache[$handlerClassName] = $methodReflection->getParameters();
diff --git a/src/DocBlock/TagFactory.php b/src/DocBlock/TagFactory.php
index c0868dcbefda0acbb2fb40f51db0e92926d415fc..a6f1ae8d5d57109cfeb389ef35d808de27c2709f 100644
--- a/src/DocBlock/TagFactory.php
+++ b/src/DocBlock/TagFactory.php
@@ -14,9 +14,9 @@ declare(strict_types=1);
 namespace phpDocumentor\Reflection\DocBlock;
 
 use InvalidArgumentException;
-use phpDocumentor\Reflection\Types\Context as TypeContext;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
 
-interface TagFactory
+interface TagFactory extends Factory
 {
     /**
      * Adds a parameter to the service locator that can be injected in a tag's factory method.
@@ -40,17 +40,6 @@ interface TagFactory
      */
     public function addParameter(string $name, $value): void;
 
-    /**
-     * Factory method responsible for instantiating the correct sub type.
-     *
-     * @param string $tagLine The text for this tag, including description.
-     *
-     * @return Tag A new tag object.
-     *
-     * @throws InvalidArgumentException If an invalid tag line was presented.
-     */
-    public function create(string $tagLine, ?TypeContext $context = null): Tag;
-
     /**
      * Registers a service with the Service Locator using the FQCN of the class or the alias, if provided.
      *
@@ -71,7 +60,7 @@ interface TagFactory
      *
      * @param string                    $tagName Name of tag to register a handler for. When registering a namespaced
      *                                   tag, the full name, along with a prefixing slash MUST be provided.
-     * @param class-string<Tag>         $handler FQCN of handler.
+     * @param class-string<Tag>|Factory $handler FQCN of handler.
      *
      * @throws InvalidArgumentException If the tag name is not a string.
      * @throws InvalidArgumentException If the tag name is namespaced (contains backslashes) but
@@ -80,5 +69,5 @@ interface TagFactory
      * @throws InvalidArgumentException If the handler is not an existing class.
      * @throws InvalidArgumentException If the handler does not implement the {@see Tag} interface.
      */
-    public function registerTagHandler(string $tagName, string $handler): void;
+    public function registerTagHandler(string $tagName, $handler): void;
 }
diff --git a/src/DocBlock/Tags/Author.php b/src/DocBlock/Tags/Author.php
index ae09ecf4211625d4583fe40771491f462891a2a9..290e5a9574962d5e058312703c6a9bcf1b27e73f 100644
--- a/src/DocBlock/Tags/Author.php
+++ b/src/DocBlock/Tags/Author.php
@@ -27,13 +27,13 @@ use const FILTER_VALIDATE_EMAIL;
 final class Author extends BaseTag implements Factory\StaticMethod
 {
     /** @var string register that this is the author tag. */
-    protected $name = 'author';
+    protected string $name = 'author';
 
     /** @var string The name of the author */
-    private $authorName;
+    private string $authorName;
 
     /** @var string The email of the author */
-    private $authorEmail;
+    private string $authorEmail;
 
     /**
      * Initializes this tag with the author name and e-mail.
diff --git a/src/DocBlock/Tags/BaseTag.php b/src/DocBlock/Tags/BaseTag.php
index a28d5bf98e01822786dffabbaf921d0db0fdc54e..98b0d881dbc8f8cd765a8ef08d8ad29e405287b7 100644
--- a/src/DocBlock/Tags/BaseTag.php
+++ b/src/DocBlock/Tags/BaseTag.php
@@ -22,10 +22,10 @@ use phpDocumentor\Reflection\DocBlock\Description;
 abstract class BaseTag implements DocBlock\Tag
 {
     /** @var string Name of the tag */
-    protected $name = '';
+    protected string $name = '';
 
     /** @var Description|null Description of the tag. */
-    protected $description;
+    protected ?Description $description = null;
 
     /**
      * Gets the name of this tag.
diff --git a/src/DocBlock/Tags/Covers.php b/src/DocBlock/Tags/Covers.php
index 3eff9d8bc143dbf2b4b44e4254f6e2ffd81f3561..022594e20c29739fdae68a2779b8850e42d62f9d 100644
--- a/src/DocBlock/Tags/Covers.php
+++ b/src/DocBlock/Tags/Covers.php
@@ -29,11 +29,9 @@ use function explode;
  */
 final class Covers extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'covers';
+    protected string $name = 'covers';
 
-    /** @var Fqsen */
-    private $refers;
+    private Fqsen $refers;
 
     /**
      * Initializes this tag.
diff --git a/src/DocBlock/Tags/Deprecated.php b/src/DocBlock/Tags/Deprecated.php
index dbcad28c053cc153ad5b06a5ae7def14fc8241c1..a55cd914a40f1e08a3fcd392f04d3b05e5b41f92 100644
--- a/src/DocBlock/Tags/Deprecated.php
+++ b/src/DocBlock/Tags/Deprecated.php
@@ -25,8 +25,7 @@ use function preg_match;
  */
 final class Deprecated extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'deprecated';
+    protected string $name = 'deprecated';
 
     /**
      * PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Deprecated extends BaseTag implements Factory\StaticMethod
     )';
 
     /** @var string|null The version vector. */
-    private $version;
+    private ?string $version = null;
 
     public function __construct(?string $version = null, ?Description $description = null)
     {
diff --git a/src/DocBlock/Tags/Example.php b/src/DocBlock/Tags/Example.php
index 825355aaf78920248367c01eec2785df73930caf..fd9ef6eb400499bf73a7aeb71213f2aafa99154b 100644
--- a/src/DocBlock/Tags/Example.php
+++ b/src/DocBlock/Tags/Example.php
@@ -29,22 +29,19 @@ use function trim;
 final class Example implements Tag, Factory\StaticMethod
 {
     /** @var string Path to a file to use as an example. May also be an absolute URI. */
-    private $filePath;
+    private string $filePath;
 
     /**
      * @var bool Whether the file path component represents an URI. This determines how the file portion
      *     appears at {@link getContent()}.
      */
-    private $isURI;
+    private bool $isURI;
 
-    /** @var int */
-    private $startingLine;
+    private int $startingLine;
 
-    /** @var int */
-    private $lineCount;
+    private int $lineCount;
 
-    /** @var string|null */
-    private $content;
+    private ?string $content = null;
 
     public function __construct(
         string $filePath,
diff --git a/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a5f8e2ccf0d2dba53ef87de49276786c5afbde4
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/AbstractPHPStanFactory.php
@@ -0,0 +1,73 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ *  For the full copyright and license information, please view the LICENSE
+ *  file that was distributed with this source code.
+ *
+ *  @link      http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+use PHPStan\PhpDocParser\Lexer\Lexer;
+use PHPStan\PhpDocParser\Parser\ConstExprParser;
+use PHPStan\PhpDocParser\Parser\PhpDocParser;
+use PHPStan\PhpDocParser\Parser\TokenIterator;
+use PHPStan\PhpDocParser\Parser\TypeParser;
+use RuntimeException;
+
+/**
+ * Factory class creating tags using phpstan's parser
+ *
+ * This class uses {@see PHPStanFactory} implementations to create tags
+ * from the ast of the phpstan docblock parser.
+ *
+ * @internal This class is not part of the BC promise of this library.
+ */
+class AbstractPHPStanFactory implements Factory
+{
+    private PhpDocParser $parser;
+    private Lexer $lexer;
+    /** @var PHPStanFactory[] */
+    private array $factories;
+
+    public function __construct(PHPStanFactory ...$factories)
+    {
+        $this->lexer = new Lexer();
+        $constParser = new ConstExprParser();
+        $this->parser = new PhpDocParser(new TypeParser($constParser), $constParser);
+        $this->factories = $factories;
+    }
+
+    public function create(string $tagLine, ?TypeContext $context = null): Tag
+    {
+        $tokens = $this->lexer->tokenize($tagLine);
+        $ast = $this->parser->parseTag(new TokenIterator($tokens));
+
+        if ($context === null) {
+            $context = new TypeContext('');
+        }
+
+        try {
+            foreach ($this->factories as $factory) {
+                if ($factory->supports($ast, $context)) {
+                    return $factory->create($ast, $context);
+                }
+            }
+        } catch (RuntimeException $e) {
+            return InvalidTag::create((string) $ast->value, 'method')->withError($e);
+        }
+
+        return InvalidTag::create(
+            (string) $ast->value,
+            $ast->name
+        );
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/Factory.php b/src/DocBlock/Tags/Factory/Factory.php
new file mode 100644
index 0000000000000000000000000000000000000000..190d3ff85b51efc1fec5ae0372b458bc13bc3f6a
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/Factory.php
@@ -0,0 +1,41 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ *  For the full copyright and license information, please view the LICENSE
+ *  file that was distributed with this source code.
+ *
+ *  @link      http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use InvalidArgumentException;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\Types\Context as TypeContext;
+
+interface Factory
+{
+    /**
+     * Factory method responsible for instantiating the correct sub type.
+     *
+     * @param string $tagLine The text for this tag, including description.
+     *
+     * @return Tag A new tag object.
+     *
+     * @throws InvalidArgumentException If an invalid tag line was presented.
+     */
+    public function create(string $tagLine, ?TypeContext $context = null): Tag;
+}
diff --git a/src/DocBlock/Tags/Factory/MethodFactory.php b/src/DocBlock/Tags/Factory/MethodFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..920be8451659ae038a1becfae69d06e6f089e14e
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/MethodFactory.php
@@ -0,0 +1,81 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Void_;
+use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\MethodTagValueParameterNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use Webmozart\Assert\Assert;
+
+use function array_map;
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class MethodFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, MethodTagValueNode::class);
+
+        return new Method(
+            $tagValue->methodName,
+            [],
+            $this->createReturnType($tagValue, $context),
+            $tagValue->isStatic,
+            $this->descriptionFactory->create($tagValue->description, $context),
+            false,
+            array_map(
+                function (MethodTagValueParameterNode $param) use ($context) {
+                    return new MethodParameter(
+                        trim($param->parameterName, '$'),
+                        $param->type === null ? new Mixed_() : $this->typeResolver->createType(
+                            $param->type,
+                            $context
+                        ),
+                        $param->isReference,
+                        $param->isVariadic,
+                        (string) $param->defaultValue
+                    );
+                },
+                $tagValue->parameters
+            ),
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof MethodTagValueNode;
+    }
+
+    private function createReturnType(MethodTagValueNode $tagValue, Context $context): Type
+    {
+        if ($tagValue->returnType === null) {
+            return new Void_();
+        }
+
+        return $this->typeResolver->createType($tagValue->returnType, $context);
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/PHPStanFactory.php b/src/DocBlock/Tags/Factory/PHPStanFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..cf04a06e64e134957bfd5071ccb69b5333d20ead
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PHPStanFactory.php
@@ -0,0 +1,16 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+
+interface PHPStanFactory
+{
+    public function create(PhpDocTagNode $node, Context $context): Tag;
+
+    public function supports(PhpDocTagNode $node, Context $context): bool;
+}
diff --git a/src/DocBlock/Tags/Factory/ParamFactory.php b/src/DocBlock/Tags/Factory/ParamFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..8e9bcaaca2acb188422b4e365df6971e0ee5321d
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/ParamFactory.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use Doctrine\Deprecations\Deprecation;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\InvalidTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\TypelessParamTagValueNode;
+use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
+use PHPStan\PhpDocParser\Ast\Type\OffsetAccessTypeNode;
+use Webmozart\Assert\Assert;
+
+use function sprintf;
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class ParamFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+
+        if ($tagValue instanceof InvalidTagValueNode) {
+            Deprecation::trigger(
+                'phpdocumentor/reflection-docblock',
+                'https://github.com/phpDocumentor/ReflectionDocBlock/issues/362',
+                sprintf(
+                    'Param tag value "%s" is invalid, falling back to legacy parsing. Please update your docblocks.',
+                    $tagValue->value
+                )
+            );
+
+            return Param::create($tagValue->value, $this->typeResolver, $this->descriptionFactory, $context);
+        }
+
+        Assert::isInstanceOfAny(
+            $tagValue,
+            [
+                ParamTagValueNode::class,
+                TypelessParamTagValueNode::class,
+            ]
+        );
+
+        if (($tagValue->type ?? null) instanceof OffsetAccessTypeNode) {
+            return InvalidTag::create(
+                (string) $tagValue,
+                'param'
+            );
+        }
+
+        return new Param(
+            trim($tagValue->parameterName, '$'),
+            $this->typeResolver->createType($tagValue->type ?? new IdentifierTypeNode('mixed'), $context),
+            $tagValue->isVariadic,
+            $this->descriptionFactory->create($tagValue->description, $context),
+            $tagValue->isReference
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof ParamTagValueNode
+            || $node->value instanceof TypelessParamTagValueNode
+            || $node->name === '@param';
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyFactory.php b/src/DocBlock/Tags/Factory/PropertyFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..83a18e8a64bde7ee76a3f974efb5064190e548f3
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Property;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+        return new Property(
+            trim($tagValue->propertyName, '$'),
+            $this->typeResolver->createType($tagValue->type, $context),
+            $this->descriptionFactory->create($tagValue->description, $context)
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof PropertyTagValueNode && $node->name === '@property';
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyReadFactory.php b/src/DocBlock/Tags/Factory/PropertyReadFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..be443ab6af218b2adf986102d328b2b6bfa091f6
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyReadFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyReadFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->typeResolver = $typeResolver;
+        $this->descriptionFactory = $descriptionFactory;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+        return new PropertyRead(
+            trim($tagValue->propertyName, '$'),
+            $this->typeResolver->createType($tagValue->type, $context),
+            $this->descriptionFactory->create($tagValue->description, $context)
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof PropertyTagValueNode && $node->name === '@property-read';
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/PropertyWriteFactory.php b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..08cf75342cdc9972f0205fd34f1efcc2998b4cdf
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/PropertyWriteFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PropertyTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class PropertyWriteFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, PropertyTagValueNode::class);
+
+        return new PropertyWrite(
+            trim($tagValue->propertyName, '$'),
+            $this->typeResolver->createType($tagValue->type, $context),
+            $this->descriptionFactory->create($tagValue->description, $context)
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof PropertyTagValueNode && $node->name === '@property-write';
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/ReturnFactory.php b/src/DocBlock/Tags/Factory/ReturnFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..8ebe5ad48cb5761f261708d289f852bf476b62d1
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/ReturnFactory.php
@@ -0,0 +1,45 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
+use Webmozart\Assert\Assert;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class ReturnFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, ReturnTagValueNode::class);
+
+        return new Return_(
+            $this->typeResolver->createType($tagValue->type, $context),
+            $this->descriptionFactory->create($tagValue->description, $context)
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof ReturnTagValueNode;
+    }
+}
diff --git a/src/DocBlock/Tags/Factory/VarFactory.php b/src/DocBlock/Tags/Factory/VarFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..79ffdf12b8a0884b1404773c1568e286825bbcc7
--- /dev/null
+++ b/src/DocBlock/Tags/Factory/VarFactory.php
@@ -0,0 +1,48 @@
+<?php
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\TypeResolver;
+use phpDocumentor\Reflection\Types\Context;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
+use Webmozart\Assert\Assert;
+
+use function trim;
+
+/**
+ * @internal This class is not part of the BC promise of this library.
+ */
+final class VarFactory implements PHPStanFactory
+{
+    private DescriptionFactory $descriptionFactory;
+    private TypeResolver $typeResolver;
+
+    public function __construct(TypeResolver $typeResolver, DescriptionFactory $descriptionFactory)
+    {
+        $this->descriptionFactory = $descriptionFactory;
+        $this->typeResolver = $typeResolver;
+    }
+
+    public function create(PhpDocTagNode $node, Context $context): Tag
+    {
+        $tagValue = $node->value;
+        Assert::isInstanceOf($tagValue, VarTagValueNode::class);
+
+        return new Var_(
+            trim($tagValue->variableName, '$'),
+            $this->typeResolver->createType($tagValue->type, $context),
+            $this->descriptionFactory->create($tagValue->description, $context)
+        );
+    }
+
+    public function supports(PhpDocTagNode $node, Context $context): bool
+    {
+        return $node->value instanceof VarTagValueNode;
+    }
+}
diff --git a/src/DocBlock/Tags/Formatter/AlignFormatter.php b/src/DocBlock/Tags/Formatter/AlignFormatter.php
index 946443438152fe58170210a131c08bcd350af4fc..ea5c16f5affe154d465249de493432d4b39ec6f5 100644
--- a/src/DocBlock/Tags/Formatter/AlignFormatter.php
+++ b/src/DocBlock/Tags/Formatter/AlignFormatter.php
@@ -23,7 +23,7 @@ use function strlen;
 class AlignFormatter implements Formatter
 {
     /** @var int The maximum tag name length. */
-    protected $maxLen = 0;
+    protected int $maxLen = 0;
 
     /**
      * @param Tag[] $tags All tags that should later be aligned with the formatter.
diff --git a/src/DocBlock/Tags/InvalidTag.php b/src/DocBlock/Tags/InvalidTag.php
index 4e6abb8c4fffb29626d45f8dfe1ceb0cb2e33ef0..c7d3cd54ec67fc712d51565fc6cb286c8b7aec91 100644
--- a/src/DocBlock/Tags/InvalidTag.php
+++ b/src/DocBlock/Tags/InvalidTag.php
@@ -32,14 +32,11 @@ use function sprintf;
  */
 final class InvalidTag implements Tag
 {
-    /** @var string */
-    private $name;
+    private string $name;
 
-    /** @var string */
-    private $body;
+    private string $body;
 
-    /** @var Throwable|null */
-    private $throwable;
+    private ?Throwable $throwable = null;
 
     private function __construct(string $name, string $body)
     {
diff --git a/src/DocBlock/Tags/Link.php b/src/DocBlock/Tags/Link.php
index ee242e3b24d861a952a8867e83ee23e988eab69b..fcb6ec193e00925ad3588e23ccc1ed49c3b02f47 100644
--- a/src/DocBlock/Tags/Link.php
+++ b/src/DocBlock/Tags/Link.php
@@ -24,11 +24,9 @@ use Webmozart\Assert\Assert;
  */
 final class Link extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'link';
+    protected string $name = 'link';
 
-    /** @var string */
-    private $link;
+    private string $link;
 
     /**
      * Initializes a link to a URL.
diff --git a/src/DocBlock/Tags/Method.php b/src/DocBlock/Tags/Method.php
index f08bfffdae44bbb5e117ff9ab7f9775de052dede..471ebe95525a6266ee5ec4cb5027875e7d1d46ac 100644
--- a/src/DocBlock/Tags/Method.php
+++ b/src/DocBlock/Tags/Method.php
@@ -24,6 +24,7 @@ use phpDocumentor\Reflection\Types\Void_;
 use Webmozart\Assert\Assert;
 
 use function array_keys;
+use function array_map;
 use function explode;
 use function implode;
 use function is_string;
@@ -31,34 +32,33 @@ use function preg_match;
 use function sort;
 use function strpos;
 use function substr;
+use function trigger_error;
 use function trim;
 use function var_export;
 
+use const E_USER_DEPRECATED;
+
 /**
  * Reflection class for an {@}method in a Docblock.
  */
 final class Method extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'method';
+    protected string $name = 'method';
 
-    /** @var string */
-    private $methodName;
+    private string $methodName;
 
-    /**
-     * @phpstan-var array<int, array{name: string, type: Type}>
-     * @var array<int, array<string, Type|string>>
-     */
-    private $arguments;
+    private bool $isStatic;
+
+    private Type $returnType;
 
-    /** @var bool */
-    private $isStatic;
+    private bool $returnsReference;
 
-    /** @var Type */
-    private $returnType;
+    /** @var MethodParameter[] */
+    private array $parameters;
 
     /**
      * @param array<int, array<string, Type|string>> $arguments
+     * @param MethodParameter[] $parameters
      * @phpstan-param array<int, array{name: string, type: Type}|string> $arguments
      */
     public function __construct(
@@ -66,7 +66,9 @@ final class Method extends BaseTag implements Factory\StaticMethod
         array $arguments = [],
         ?Type $returnType = null,
         bool $static = false,
-        ?Description $description = null
+        ?Description $description = null,
+        bool $returnsReference = false,
+        ?array $parameters = null
     ) {
         Assert::stringNotEmpty($methodName);
 
@@ -74,19 +76,31 @@ final class Method extends BaseTag implements Factory\StaticMethod
             $returnType = new Void_();
         }
 
-        $this->methodName  = $methodName;
-        $this->arguments   = $this->filterArguments($arguments);
-        $this->returnType  = $returnType;
-        $this->isStatic    = $static;
-        $this->description = $description;
+        $arguments = $this->filterArguments($arguments);
+
+        $this->methodName       = $methodName;
+        $this->returnType       = $returnType;
+        $this->isStatic         = $static;
+        $this->description      = $description;
+        $this->returnsReference = $returnsReference;
+        $this->parameters = $parameters ?? $this->fromLegacyArguments($arguments);
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): ?self {
+        trigger_error(
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+            E_USER_DEPRECATED
+        );
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
@@ -95,11 +109,13 @@ final class Method extends BaseTag implements Factory\StaticMethod
         // 2. optionally the keyword "static" followed by whitespace
         // 3. optionally a word with underscores followed by whitespace : as
         //    type for the return value
-        // 4. then optionally a word with underscores followed by () and
+        // 4. optionally an ampersand followed or not by whitespace : as
+        //    a reference
+        // 5. then optionally a word with underscores followed by () and
         //    whitespace : as method name as used by phpDocumentor
-        // 5. then a word with underscores, followed by ( and any character
+        // 6. then a word with underscores, followed by ( and any character
         //    until a ) and whitespace : as method name with signature
-        // 6. any remaining text : as description
+        // 7. any remaining text : as description
         if (
             !preg_match(
                 '/^
@@ -122,6 +138,11 @@ final class Method extends BaseTag implements Factory\StaticMethod
                     )
                     \s+
                 )?
+                # Returns reference
+                (?:
+                    (&)
+                    \s*
+                )?
                 # Method name
                 ([\w_]+)
                 # Arguments
@@ -139,7 +160,7 @@ final class Method extends BaseTag implements Factory\StaticMethod
             return null;
         }
 
-        [, $static, $returnType, $methodName, $argumentLines, $description] = $matches;
+        [, $static, $returnType, $returnsReference, $methodName, $argumentLines, $description] = $matches;
 
         $static = $static === 'static';
 
@@ -147,6 +168,8 @@ final class Method extends BaseTag implements Factory\StaticMethod
             $returnType = 'void';
         }
 
+        $returnsReference = $returnsReference === '&';
+
         $returnType  = $typeResolver->resolve($returnType, $context);
         $description = $descriptionFactory->create($description, $context);
 
@@ -172,7 +195,14 @@ final class Method extends BaseTag implements Factory\StaticMethod
             }
         }
 
-        return new static($methodName, $arguments, $returnType, $static, $description);
+        return new static(
+            $methodName,
+            $arguments,
+            $returnType,
+            $static,
+            $description,
+            $returnsReference
+        );
     }
 
     /**
@@ -184,12 +214,27 @@ final class Method extends BaseTag implements Factory\StaticMethod
     }
 
     /**
+     * @deprecated Method deprecated, use {@see self::getParameters()}
+     *
      * @return array<int, array<string, Type|string>>
      * @phpstan-return array<int, array{name: string, type: Type}>
      */
     public function getArguments(): array
     {
-        return $this->arguments;
+        trigger_error('Method deprecated, use ::getParameters()', E_USER_DEPRECATED);
+
+        return array_map(
+            static function (MethodParameter $methodParameter) {
+                return ['name' => $methodParameter->getName(), 'type' => $methodParameter->getType()];
+            },
+            $this->parameters
+        );
+    }
+
+    /** @return MethodParameter[] */
+    public function getParameters(): array
+    {
+        return $this->parameters;
     }
 
     /**
@@ -207,11 +252,19 @@ final class Method extends BaseTag implements Factory\StaticMethod
         return $this->returnType;
     }
 
+    public function returnsReference(): bool
+    {
+        return $this->returnsReference;
+    }
+
     public function __toString(): string
     {
         $arguments = [];
-        foreach ($this->arguments as $argument) {
-            $arguments[] = $argument['type'] . ' $' . $argument['name'];
+        foreach ($this->parameters as $parameter) {
+            $arguments[] = $parameter->getType() . ' ' .
+                ($parameter->isReference() ? '&' : '') .
+                ($parameter->isVariadic() ? '...' : '') .
+                '$' . $parameter->getName();
         }
 
         $argumentStr = '(' . implode(', ', $arguments) . ')';
@@ -228,9 +281,11 @@ final class Method extends BaseTag implements Factory\StaticMethod
 
         $methodName = $this->methodName;
 
+        $reference = $this->returnsReference ? '&' : '';
+
         return $static
             . ($returnType !== '' ? ($static !== '' ? ' ' : '') . $returnType : '')
-            . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $methodName : '')
+            . ($methodName !== '' ? ($static !== '' || $returnType !== '' ? ' ' : '') . $reference . $methodName : '')
             . $argumentStr
             . ($description !== '' ? ' ' . $description : '');
     }
@@ -276,4 +331,28 @@ final class Method extends BaseTag implements Factory\StaticMethod
 
         return $argument;
     }
+
+    /**
+     * @param array{name: string, type: Type} $arguments
+     * @phpstan-param array<int, array{name: string, type: Type}> $arguments
+     *
+     * @return MethodParameter[]
+     */
+    private function fromLegacyArguments(array $arguments): array
+    {
+        trigger_error(
+            'Create method parameters via legacy format is deprecated add parameters via the constructor',
+            E_USER_DEPRECATED
+        );
+
+        return array_map(
+            static function ($arg) {
+                return new MethodParameter(
+                    $arg['name'],
+                    $arg['type']
+                );
+            },
+            $arguments
+        );
+    }
 }
diff --git a/src/DocBlock/Tags/MethodParameter.php b/src/DocBlock/Tags/MethodParameter.php
new file mode 100644
index 0000000000000000000000000000000000000000..0c85d41ddf976aa40f99e0355b88f532d9e93f16
--- /dev/null
+++ b/src/DocBlock/Tags/MethodParameter.php
@@ -0,0 +1,67 @@
+<?php
+/**
+ * This file is part of phpDocumentor.
+ *
+ *  For the full copyright and license information, please view the LICENSE
+ *  file that was distributed with this source code.
+ *
+ *  @link      http://phpdoc.org
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags;
+
+use phpDocumentor\Reflection\Type;
+
+final class MethodParameter
+{
+    private Type $type;
+
+    private bool $isReference;
+
+    private bool $isVariadic;
+
+    private string $name;
+
+    private ?string $defaultValue = null;
+
+    public function __construct(
+        string $name,
+        Type $type,
+        bool $isReference = false,
+        bool $isVariadic = false,
+        ?string $defaultValue = null
+    ) {
+        $this->type = $type;
+        $this->isReference = $isReference;
+        $this->isVariadic = $isVariadic;
+        $this->name = $name;
+        $this->defaultValue = $defaultValue;
+    }
+
+    public function getName(): string
+    {
+        return $this->name;
+    }
+
+    public function getType(): Type
+    {
+        return $this->type;
+    }
+
+    public function isReference(): bool
+    {
+        return $this->isReference;
+    }
+
+    public function isVariadic(): bool
+    {
+        return $this->isVariadic;
+    }
+
+    public function getDefaultValue(): ?string
+    {
+        return $this->defaultValue;
+    }
+}
diff --git a/src/DocBlock/Tags/Param.php b/src/DocBlock/Tags/Param.php
index 3399649b83b18f9e8083ff2bbf7ad94f2fe5ea46..19b1b5fbd5ac0e7360ed3e7da7adbcd112462102 100644
--- a/src/DocBlock/Tags/Param.php
+++ b/src/DocBlock/Tags/Param.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -34,14 +35,13 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 final class Param extends TagWithType implements Factory\StaticMethod
 {
-    /** @var string|null */
-    private $variableName;
+    private ?string $variableName = null;
 
     /** @var bool determines whether this is a variadic argument */
-    private $isVariadic;
+    private bool $isVariadic;
 
     /** @var bool determines whether this is passed by reference */
-    private $isReference;
+    private bool $isReference;
 
     public function __construct(
         ?string $variableName,
@@ -58,12 +58,23 @@ final class Param extends TagWithType implements Factory\StaticMethod
         $this->isReference  = $isReference;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
+
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Property.php b/src/DocBlock/Tags/Property.php
index 2521fb3f01b9c57eee09c4fe9139134d25a08b78..1287b6cc2ba02cc2ec1de7cf8142cb5c1a69ea49 100644
--- a/src/DocBlock/Tags/Property.php
+++ b/src/DocBlock/Tags/Property.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 final class Property extends TagWithType implements Factory\StaticMethod
 {
-    /** @var string|null */
-    protected $variableName;
+    protected ?string $variableName = null;
 
     public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
     {
@@ -47,12 +47,23 @@ final class Property extends TagWithType implements Factory\StaticMethod
         $this->description  = $description;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
+
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/PropertyRead.php b/src/DocBlock/Tags/PropertyRead.php
index 9491b39c3343fd9a1777983d5db4bb38e6128d25..2cf8e61a615cd06234ed7aed00df5438f316961e 100644
--- a/src/DocBlock/Tags/PropertyRead.php
+++ b/src/DocBlock/Tags/PropertyRead.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 final class PropertyRead extends TagWithType implements Factory\StaticMethod
 {
-    /** @var string|null */
-    protected $variableName;
+    protected ?string $variableName = null;
 
     public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
     {
@@ -47,12 +47,23 @@ final class PropertyRead extends TagWithType implements Factory\StaticMethod
         $this->description  = $description;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
+
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/PropertyWrite.php b/src/DocBlock/Tags/PropertyWrite.php
index 2bfdac6a0673d40d62a5abdcfa35452a4067b7cc..57e7eb103e9ab10be260c48575fced55b46bd37b 100644
--- a/src/DocBlock/Tags/PropertyWrite.php
+++ b/src/DocBlock/Tags/PropertyWrite.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 final class PropertyWrite extends TagWithType implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $variableName;
+    protected string $variableName;
 
     public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
     {
@@ -47,12 +47,23 @@ final class PropertyWrite extends TagWithType implements Factory\StaticMethod
         $this->description  = $description;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
+
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Reference/Fqsen.php b/src/DocBlock/Tags/Reference/Fqsen.php
index 532003dd8a68095c25c77792c5f7ce4bded742e5..e4e7e31c6317ad5f3f30d754caf70d983163974a 100644
--- a/src/DocBlock/Tags/Reference/Fqsen.php
+++ b/src/DocBlock/Tags/Reference/Fqsen.php
@@ -20,8 +20,7 @@ use phpDocumentor\Reflection\Fqsen as RealFqsen;
  */
 final class Fqsen implements Reference
 {
-    /** @var RealFqsen */
-    private $fqsen;
+    private RealFqsen $fqsen;
 
     public function __construct(RealFqsen $fqsen)
     {
diff --git a/src/DocBlock/Tags/Reference/Url.php b/src/DocBlock/Tags/Reference/Url.php
index edfba3fde8a5eb9e01bc492b53a0a2ecf28a7f00..5954a471796039d43a5c14e7c5fc3ec1876ef0ca 100644
--- a/src/DocBlock/Tags/Reference/Url.php
+++ b/src/DocBlock/Tags/Reference/Url.php
@@ -20,8 +20,7 @@ use Webmozart\Assert\Assert;
  */
 final class Url implements Reference
 {
-    /** @var string */
-    private $uri;
+    private string $uri;
 
     public function __construct(string $uri)
     {
diff --git a/src/DocBlock/Tags/Return_.php b/src/DocBlock/Tags/Return_.php
index f021b6092ec6ca5bfa9b5d783092719efe93ebf4..f130760a4ee4b75c500557bb4200861fe363b64a 100644
--- a/src/DocBlock/Tags/Return_.php
+++ b/src/DocBlock/Tags/Return_.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -32,12 +33,23 @@ final class Return_ extends TagWithType implements Factory\StaticMethod
         $this->description = $description;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
+
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
 
diff --git a/src/DocBlock/Tags/See.php b/src/DocBlock/Tags/See.php
index a194c7dedabb6e89682525b0691cfa65c9b8c1ff..e7330e887efab4dce6c2b6f7238647571a4eb642 100644
--- a/src/DocBlock/Tags/See.php
+++ b/src/DocBlock/Tags/See.php
@@ -33,11 +33,9 @@ use function preg_match;
  */
 final class See extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'see';
+    protected string $name = 'see';
 
-    /** @var Reference */
-    protected $refers;
+    protected Reference $refers;
 
     /**
      * Initializes this tag.
diff --git a/src/DocBlock/Tags/Since.php b/src/DocBlock/Tags/Since.php
index 54af43cd428be1b1f1df56ca5ce780b8e61848b8..24400fa1db5f8c5ffbb06b10e88806906d5468a6 100644
--- a/src/DocBlock/Tags/Since.php
+++ b/src/DocBlock/Tags/Since.php
@@ -25,8 +25,7 @@ use function preg_match;
  */
 final class Since extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'since';
+    protected string $name = 'since';
 
     /**
      * PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Since extends BaseTag implements Factory\StaticMethod
     )';
 
     /** @var string|null The version vector. */
-    private $version;
+    private ?string $version = null;
 
     public function __construct(?string $version = null, ?Description $description = null)
     {
diff --git a/src/DocBlock/Tags/Source.php b/src/DocBlock/Tags/Source.php
index 8b8c0fb47b8162b8b9be913ab386d35123c1d929..f6b4f57fad05691fc141980aa5e42fd0bc64a8fe 100644
--- a/src/DocBlock/Tags/Source.php
+++ b/src/DocBlock/Tags/Source.php
@@ -25,14 +25,13 @@ use function preg_match;
  */
 final class Source extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'source';
+    protected string $name = 'source';
 
     /** @var int The starting line, relative to the structural element's location. */
-    private $startingLine;
+    private int $startingLine;
 
     /** @var int|null The number of lines, relative to the starting line. NULL means "to the end". */
-    private $lineCount;
+    private ?int $lineCount = null;
 
     /**
      * @param int|string      $startingLine should be a to int convertible value
diff --git a/src/DocBlock/Tags/TagWithType.php b/src/DocBlock/Tags/TagWithType.php
index 158578bd2e423b87b5ec0b45fc800747646e175d..271c41b539555845e646bfa1cb32cfe7c49398e5 100644
--- a/src/DocBlock/Tags/TagWithType.php
+++ b/src/DocBlock/Tags/TagWithType.php
@@ -13,9 +13,11 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use InvalidArgumentException;
 use phpDocumentor\Reflection\Type;
 
 use function in_array;
+use function sprintf;
 use function strlen;
 use function substr;
 use function trim;
@@ -23,7 +25,7 @@ use function trim;
 abstract class TagWithType extends BaseTag
 {
     /** @var ?Type */
-    protected $type;
+    protected ?Type $type = null;
 
     /**
      * Returns the type section of the variable.
@@ -59,6 +61,12 @@ abstract class TagWithType extends BaseTag
             }
         }
 
+        if ($nestingLevel < 0 || $nestingLevel > 0) {
+            throw new InvalidArgumentException(
+                sprintf('Could not find type in %s, please check for malformed notations', $body)
+            );
+        }
+
         $description = trim(substr($body, strlen($type)));
 
         return [$type, $description];
diff --git a/src/DocBlock/Tags/Uses.php b/src/DocBlock/Tags/Uses.php
index b72f403474c95f62b9cfbae4ae26472b47cf350a..d9aa3608fece147c9f293ba44a524743e38eabcf 100644
--- a/src/DocBlock/Tags/Uses.php
+++ b/src/DocBlock/Tags/Uses.php
@@ -29,11 +29,9 @@ use function explode;
  */
 final class Uses extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'uses';
+    protected string $name = 'uses';
 
-    /** @var Fqsen */
-    protected $refers;
+    protected Fqsen $refers;
 
     /**
      * Initializes this tag.
diff --git a/src/DocBlock/Tags/Var_.php b/src/DocBlock/Tags/Var_.php
index fa1f9dbf656c6fa82921b320bcb616281ce95fa4..0a79ab94dec4ab74e03d1aa94d1853b9c690310d 100644
--- a/src/DocBlock/Tags/Var_.php
+++ b/src/DocBlock/Tags/Var_.php
@@ -13,6 +13,7 @@ declare(strict_types=1);
 
 namespace phpDocumentor\Reflection\DocBlock\Tags;
 
+use Doctrine\Deprecations\Deprecation;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\Type;
@@ -34,8 +35,7 @@ use const PREG_SPLIT_DELIM_CAPTURE;
  */
 final class Var_ extends TagWithType implements Factory\StaticMethod
 {
-    /** @var string|null */
-    protected $variableName = '';
+    protected ?string $variableName = '';
 
     public function __construct(?string $variableName, ?Type $type = null, ?Description $description = null)
     {
@@ -47,12 +47,22 @@ final class Var_ extends TagWithType implements Factory\StaticMethod
         $this->description  = $description;
     }
 
+    /**
+     * @deprecated Create using static factory is deprecated,
+     *  this method should not be called directly by library consumers
+     */
     public static function create(
         string $body,
         ?TypeResolver $typeResolver = null,
         ?DescriptionFactory $descriptionFactory = null,
         ?TypeContext $context = null
     ): self {
+        Deprecation::triggerIfCalledFromOutside(
+            'phpdocumentor/reflection-docblock',
+            'https://github.com/phpDocumentor/ReflectionDocBlock/issues/361',
+            'Create using static factory is deprecated, this method should not be called directly
+             by library consumers',
+        );
         Assert::stringNotEmpty($body);
         Assert::notNull($typeResolver);
         Assert::notNull($descriptionFactory);
diff --git a/src/DocBlock/Tags/Version.php b/src/DocBlock/Tags/Version.php
index f46e4b8c01dfd54e9c91a892630f547106896541..1ed25d173a828a53519ee130f24a10a461e220db 100644
--- a/src/DocBlock/Tags/Version.php
+++ b/src/DocBlock/Tags/Version.php
@@ -25,8 +25,7 @@ use function preg_match;
  */
 final class Version extends BaseTag implements Factory\StaticMethod
 {
-    /** @var string */
-    protected $name = 'version';
+    protected string $name = 'version';
 
     /**
      * PCRE regular expression matching a version vector.
@@ -45,7 +44,7 @@ final class Version extends BaseTag implements Factory\StaticMethod
     )';
 
     /** @var string|null The version vector. */
-    private $version;
+    private ?string $version = null;
 
     public function __construct(?string $version = null, ?Description $description = null)
     {
diff --git a/src/DocBlockFactory.php b/src/DocBlockFactory.php
index 37f72dd2e30b2c1296c6262de74e61ea03dcb422..1f7faf1aad10cec039776aa77b85bd363d74f7d5 100644
--- a/src/DocBlockFactory.php
+++ b/src/DocBlockFactory.php
@@ -19,6 +19,15 @@ use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
 use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
 use phpDocumentor\Reflection\DocBlock\Tag;
 use phpDocumentor\Reflection\DocBlock\TagFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\AbstractPHPStanFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory;
 use Webmozart\Assert\Assert;
 
 use function array_shift;
@@ -35,11 +44,9 @@ use function trim;
 
 final class DocBlockFactory implements DocBlockFactoryInterface
 {
-    /** @var DocBlock\DescriptionFactory */
-    private $descriptionFactory;
+    private DocBlock\DescriptionFactory $descriptionFactory;
 
-    /** @var DocBlock\TagFactory */
-    private $tagFactory;
+    private TagFactory $tagFactory;
 
     /**
      * Initializes this factory with the required subcontractors.
@@ -47,22 +54,40 @@ final class DocBlockFactory implements DocBlockFactoryInterface
     public function __construct(DescriptionFactory $descriptionFactory, TagFactory $tagFactory)
     {
         $this->descriptionFactory = $descriptionFactory;
-        $this->tagFactory         = $tagFactory;
+        $this->tagFactory = $tagFactory;
     }
 
     /**
      * Factory method for easy instantiation.
      *
-     * @param array<string, class-string<Tag>> $additionalTags
+     * @param array<string, class-string<Tag>|Factory> $additionalTags
      */
-    public static function createInstance(array $additionalTags = []): self
+    public static function createInstance(array $additionalTags = []): DocBlockFactoryInterface
     {
-        $fqsenResolver      = new FqsenResolver();
-        $tagFactory         = new StandardTagFactory($fqsenResolver);
+        $fqsenResolver = new FqsenResolver();
+        $tagFactory = new StandardTagFactory($fqsenResolver);
         $descriptionFactory = new DescriptionFactory($tagFactory);
+        $typeResolver = new TypeResolver($fqsenResolver);
+
+        $phpstanTagFactory = new AbstractPHPStanFactory(
+            new ParamFactory($typeResolver, $descriptionFactory),
+            new VarFactory($typeResolver, $descriptionFactory),
+            new ReturnFactory($typeResolver, $descriptionFactory),
+            new PropertyFactory($typeResolver, $descriptionFactory),
+            new PropertyReadFactory($typeResolver, $descriptionFactory),
+            new PropertyWriteFactory($typeResolver, $descriptionFactory),
+            new MethodFactory($typeResolver, $descriptionFactory)
+        );
 
         $tagFactory->addService($descriptionFactory);
-        $tagFactory->addService(new TypeResolver($fqsenResolver));
+        $tagFactory->addService($typeResolver);
+        $tagFactory->registerTagHandler('param', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('var', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('return', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('property', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('property-read', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('property-write', $phpstanTagFactory);
+        $tagFactory->registerTagHandler('method', $phpstanTagFactory);
 
         $docBlockFactory = new self($descriptionFactory, $tagFactory);
         foreach ($additionalTags as $tagName => $tagHandler) {
@@ -111,9 +136,9 @@ final class DocBlockFactory implements DocBlockFactoryInterface
     }
 
     /**
-     * @param class-string<Tag> $handler
+     * @param class-string<Tag>|Factory $handler
      */
-    public function registerTagHandler(string $tagName, string $handler): void
+    public function registerTagHandler(string $tagName, $handler): void
     {
         $this->tagFactory->registerTagHandler($tagName, $handler);
     }
@@ -138,6 +163,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
     }
 
     // phpcs:disable
+
     /**
      * Splits the DocBlock into a template marker, summary, description and block of tags.
      *
@@ -149,7 +175,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
      *
      * @author Richard van Velzen (@_richardJ) Special thanks to Richard for the regex responsible for the split.
      */
-    private function splitDocBlock(string $comment) : array
+    private function splitDocBlock(string $comment): array
     {
         // phpcs:enable
         // Performance improvement cheat: if the first character is an @ then only tags are in this DocBlock. This
@@ -227,7 +253,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
     /**
      * Creates the tag objects.
      *
-     * @param string        $tags    Tag block to parse.
+     * @param string $tags Tag block to parse.
      * @param Types\Context $context Context of the parsed Tag
      *
      * @return DocBlock\Tag[]
@@ -240,7 +266,7 @@ final class DocBlockFactory implements DocBlockFactoryInterface
         }
 
         $result = [];
-        $lines  = $this->splitTagBlockIntoTagLines($tags);
+        $lines = $this->splitTagBlockIntoTagLines($tags);
         foreach ($lines as $key => $tagLine) {
             $result[$key] = $this->tagFactory->create(trim($tagLine), $context);
         }
diff --git a/src/DocBlockFactoryInterface.php b/src/DocBlockFactoryInterface.php
index 9995c0c0958d3db36e2a4b6e21c4d89ce441c632..cacc382e61b68ee90414082473f0e09a66eec161 100644
--- a/src/DocBlockFactoryInterface.php
+++ b/src/DocBlockFactoryInterface.php
@@ -14,7 +14,7 @@ interface DocBlockFactoryInterface
      *
      * @param array<string, class-string<Tag>> $additionalTags
      */
-    public static function createInstance(array $additionalTags = []): DocBlockFactory;
+    public static function createInstance(array $additionalTags = []): self;
 
     /**
      * @param string|object $docblock
diff --git a/tests/integration/InterpretingDocBlocksTest.php b/tests/integration/InterpretingDocBlocksTest.php
index 2c8358cfbbd6daf570db84fc158cfa36099d0e4a..51f3e8f0e387b1e4198f6381758814c712e28c16 100644
--- a/tests/integration/InterpretingDocBlocksTest.php
+++ b/tests/integration/InterpretingDocBlocksTest.php
@@ -17,7 +17,19 @@ use Mockery as m;
 use phpDocumentor\Reflection\DocBlock\Description;
 use phpDocumentor\Reflection\DocBlock\StandardTagFactory;
 use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
 use phpDocumentor\Reflection\DocBlock\Tags\See;
+use phpDocumentor\Reflection\PseudoTypes\ConstExpression;
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Self_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
 use PHPUnit\Framework\TestCase;
 
 /**
@@ -83,7 +95,7 @@ DESCRIPTION;
             str_replace(
                 PHP_EOL,
                 "\n",
-            $descriptionText
+                $descriptionText
             ),
             $description->render()
         );
@@ -134,7 +146,7 @@ DESCRIPTION;
             str_replace(
                 PHP_EOL,
                 "\n",
-            <<<'DESCRIPTION'
+                <<<'DESCRIPTION'
 You can escape the @-sign by surrounding it with braces, for example: @. And escape a closing brace within an
 inline tag by adding an opening brace in front of it like this: }.
 
@@ -149,4 +161,111 @@ DESCRIPTION
             $foundDescription
         );
     }
+
+    public function testMultilineTags(): void
+    {
+        $docCommment = <<<DOC
+/**
+ * This is an example of a summary.
+ *
+ * @param array<
+ *   int,
+ *   string     
+ * > \$store
+ */
+DOC;
+        $factory = DocBlockFactory::createInstance();
+        $docblock = $factory->create($docCommment);
+
+        self::assertEquals(
+            [
+                new Param(
+                    'store',
+                    new Array_(
+                        new String_(),
+                        new Integer()
+                    ),
+                    false,
+                    new Description(''),
+                ),
+            ],
+            $docblock->getTags()
+        );
+
+    }
+
+    public function testMethodRegression(): void
+    {
+        $docCommment = <<<DOC
+/**
+ * This is an example of a summary.
+ *
+ * @method void setInteger(integer \$integer)
+ */
+DOC;
+        $factory = DocBlockFactory::createInstance();
+        $docblock = $factory->create($docCommment);
+
+        self::assertEquals(
+            [
+                new Method(
+                    'setInteger',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [
+                        new MethodParameter('integer', new Integer())
+                    ]
+                ),
+            ],
+            $docblock->getTags()
+        );
+    }
+
+    public function testInvalidTypeParamResultsInInvalidTag(): void
+    {
+        $docCommment = '
+/**
+ * This is an example of a summary.
+ *
+ * @param array\Foo> $test
+ */
+';
+        $factory = DocBlockFactory::createInstance();
+        $docblock = $factory->create($docCommment);
+
+        self::assertEquals(
+            [
+                InvalidTag::create(
+                    'array\Foo> $test',
+                    'param',
+                )->withError(
+                    new \InvalidArgumentException(
+                        'Could not find type in array\Foo> $test, please check for malformed notations')
+                ),
+            ],
+            $docblock->getTags()
+        );
+    }
+
+    public function testConstantReferenceTypes(): void
+    {
+        $docCommment = <<<DOC
+    /**
+     * @return self::STATUS_*
+     */
+DOC;
+
+        $factory = DocBlockFactory::createInstance();
+        $docblock = $factory->create($docCommment);
+
+        self::assertEquals(
+            [
+                new Return_(new ConstExpression(new Self_(), 'STATUS_*'), new Description('')),
+            ],
+            $docblock->getTags()
+        );
+    }
 }
diff --git a/tests/integration/ReconstitutingADocBlockTest.php b/tests/integration/ReconstitutingADocBlockTest.php
index 02da4defc4812f606b743b1d1f6c45553432abf4..aef6598c9c7301e96f9025bafeef9e65f8feb055 100644
--- a/tests/integration/ReconstitutingADocBlockTest.php
+++ b/tests/integration/ReconstitutingADocBlockTest.php
@@ -14,6 +14,9 @@ declare(strict_types=1);
 namespace phpDocumentor\Reflection;
 
 use Mockery as m;
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\Types\ContextFactory;
 use PHPUnit\Framework\TestCase;
 
 /**
@@ -40,4 +43,43 @@ class ReconstitutingADocBlockTest extends TestCase
 
         $this->assertSame($docComment, $reconstitutedDocComment);
     }
+
+
+    /**
+     * Method
+     *
+     * Method which contains a modulo sign (%) in its description.
+     *
+     * @uses \phpDocumentor\Reflection\DocBlock\Tags\Generic
+     * @uses \phpDocumentor\Reflection\DocBlock\Tags\BaseTag
+     * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
+     *
+     * @covers ::__construct
+     * @covers ::render
+     * @covers ::__toString
+     */
+    public function testDescriptionCanContainPercent(): void
+    {
+        $factory = DocBlockFactory::createInstance();
+        $contextFactory = new ContextFactory();
+
+        $method = new \ReflectionMethod(self::class, 'testDescriptionCanContainPercent');
+
+        $docblock = $factory->create(
+            $method,
+            $contextFactory->createFromReflector($method->getDeclaringClass())
+        );
+
+        $tag1 = new Generic('JoinColumn', new Description('(name="column_id", referencedColumnName="id")'));
+        $tag2 = new Generic('JoinColumn', new Description('(name="column_id_2", referencedColumnName="id")'));
+
+        $tags = [
+            $tag1,
+            $tag2,
+        ];
+
+        $fixture  = $docblock->getDescription();
+        $expected = 'Method which contains a modulo sign (%) in its description.';
+        $this->assertSame($expected, (string) $fixture);
+    }
 }
diff --git a/tests/integration/TypedTagsTest.php b/tests/integration/TypedTagsTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0f6d6516b2c2055c9adff410882fe13609209da
--- /dev/null
+++ b/tests/integration/TypedTagsTest.php
@@ -0,0 +1,194 @@
+<?php
+
+declare(strict_types=1);
+
+namespace integration;
+
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\DocBlockFactory;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\PseudoTypes\ArrayShape;
+use phpDocumentor\Reflection\PseudoTypes\ArrayShapeItem;
+use phpDocumentor\Reflection\Type;
+use phpDocumentor\Reflection\Types\Array_;
+use phpDocumentor\Reflection\Types\Callable_;
+use phpDocumentor\Reflection\Types\CallableParameter;
+use phpDocumentor\Reflection\Types\Collection;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Nullable;
+use phpDocumentor\Reflection\Types\Object_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
+use PHPUnit\Framework\TestCase;
+
+/**
+ * @coversNothing
+ */
+final class TypedTagsTest extends TestCase
+{
+    /** @dataProvider typeProvider */
+    public function testParamFormats(string $type, Type $expectedType): void
+    {
+        $docblock = <<<DOCBLOCK
+/**
+ * @param $type \$param
+ */
+DOCBLOCK;
+
+        $factory = DocBlockFactory::createInstance();
+        $phpdoc = $factory->create($docblock);
+
+        $this->assertInstanceOf(Param::class, $phpdoc->getTags()[0]);
+        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());
+    }
+
+    /** @dataProvider typeProvider */
+    public function testVarFormats(string $type, Type $expectedType): void
+    {
+        $docblock = <<<DOCBLOCK
+/**
+ * @var $type \$param
+ */
+DOCBLOCK;
+
+        $factory = DocBlockFactory::createInstance();
+        $phpdoc = $factory->create($docblock);
+
+        $this->assertInstanceOf(Var_::class, $phpdoc->getTags()[0]);
+        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getType());
+    }
+
+    /** @dataProvider typeProvider */
+    public function testMethodFormats(string $type, Type $expectedType): void
+    {
+        $docblock = <<<DOCBLOCK
+/**
+ * @method $type setValue($type \$param)
+ */
+DOCBLOCK;
+
+        $factory = DocBlockFactory::createInstance();
+        $phpdoc = $factory->create($docblock);
+
+        $this->assertInstanceOf(Method::class, $phpdoc->getTags()[0]);
+        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getReturnType());
+        $this->assertEquals($expectedType, $phpdoc->getTags()[0]->getParameters()[0]->getType());
+    }
+
+    /** @dataProvider invalidFormatsProvider */
+    public function testInvalidParam(string $type): void
+    {
+        $docblock = <<<DOCBLOCK
+/**
+ * @param $type \$param
+ */
+DOCBLOCK;
+
+        $factory = DocBlockFactory::createInstance();
+        $phpdoc = $factory->create($docblock);
+
+        $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);
+        $this->assertEquals("$type \$param", (string) $phpdoc->getTags()[0]);
+
+    }
+
+    /** @dataProvider invalidFormatsProvider */
+    public function testInvalidMethod(string $type): void
+    {
+        $docblock = <<<DOCBLOCK
+/**
+ * @method $type setValue($type \$param)
+ */
+DOCBLOCK;
+
+        $factory = DocBlockFactory::createInstance();
+        $phpdoc = $factory->create($docblock);
+
+        $this->assertInstanceOf(InvalidTag::class, $phpdoc->getTags()[0]);
+        $this->assertEquals("$type setValue($type \$param)", (string) $phpdoc->getTags()[0]);
+
+    }
+
+    public static function typeProvider(): array
+    {
+        return [
+            [
+                'int',
+                new Integer(),
+            ],
+            [
+                'integer',
+                new Integer(),
+            ],
+            [
+                'string',
+                new String_(),
+            ],
+            [
+                'T',
+                new Object_(new Fqsen('\\T')),
+            ],
+            [
+                'array',
+                new Array_(),
+            ],
+            [
+                'int[]',
+                new Array_(new Integer()),
+            ],
+            [
+                'int[][]',
+                new Array_(new Array_(new Integer())),
+            ],
+            [
+                'array<int, string>',
+                new Array_(new String_(), new Integer()),
+            ],
+            [
+                'array{
+                   foo: int,
+                   bar?: ?string
+                }',
+                new ArrayShape(
+                    new ArrayShapeItem('foo', new Integer(), false),
+                    new ArrayShapeItem('bar', new Nullable(new String_()), true),
+
+                )
+            ],
+            [
+                'Collection<int, string>',
+                new Collection(new Fqsen('\\Collection'), new String_(), new Integer()),
+            ],
+            [
+                'Collection<TKey, Tvalue>',
+                new Collection(new Fqsen('\\Collection'), new Object_(new Fqsen('\\Tvalue')), new Object_(new Fqsen('\\TKey'))),
+            ],
+            [
+                'Collection<Tvalue>',
+                new Collection(new Fqsen('\\Collection'), new Object_(new Fqsen('\\Tvalue'))),
+            ],
+            [
+                'callable(int $foo, string $bar): void',
+                new Callable_([new CallableParameter(new Integer(), 'foo'), new CallableParameter(new String_(), 'bar')], new Void_()),
+            ],
+        ];
+    }
+
+    public static function invalidFormatsProvider(): \Generator
+    {
+        yield from [
+            'invalid collection' => ['self<Tvalue>'],
+        ];
+
+        foreach (['<', '{', '('] as $badChar) {
+            yield "invalid format open $badChar" => ["array$badChar\\fooo"];
+        }
+
+        foreach (['>', '}', ')'] as $badChar) {
+            yield "invalid format close $badChar" => ["array\\fooo$badChar"];
+        }
+    }
+}
diff --git a/tests/unit/Assets/CustomTagFactory.php b/tests/unit/Assets/CustomTagFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..df4a3f6996dfd35d5d6f20b9f251e99f2c11a091
--- /dev/null
+++ b/tests/unit/Assets/CustomTagFactory.php
@@ -0,0 +1,31 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ *  For the full copyright and license information, please view the LICENSE
+ *  file that was distributed with this source code.
+ *
+ *  @link      http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\Assets;
+
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\Factory\Factory;
+use phpDocumentor\Reflection\DocBlock\Tags\Generic;
+use phpDocumentor\Reflection\Types\Context;
+
+class CustomTagFactory implements Factory
+{
+    public $class;
+
+    public function create(string $tagLine, ?Context $context = null, CustomServiceClass $class = null): Tag
+    {
+        $this->class = $class;
+
+        return new Generic('custom');
+    }
+}
diff --git a/tests/unit/DocBlock/DescriptionTest.php b/tests/unit/DocBlock/DescriptionTest.php
index b4ddb492d553ca0e5cbab73600e2f907511abadf..e1ddbd6c87b360af5c97958d96ce9d00340ddfe1 100644
--- a/tests/unit/DocBlock/DescriptionTest.php
+++ b/tests/unit/DocBlock/DescriptionTest.php
@@ -142,4 +142,31 @@ class DescriptionTest extends TestCase
         . 'inverseJoinColumns={@JoinColumn (name="column_id_2", referencedColumnName="id")})';
         $this->assertSame($expected, (string) $fixture);
     }
+
+    /**
+     * @uses \phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter
+     *
+     * @covers ::__construct
+     * @covers ::render
+     * @covers ::__toString
+     */
+    public function testDescriptionWithEscapedCharactersAndNoTagsCanBeCastToString(): void
+    {
+        //% chars are escaped in \phpDocumentor\Reflection\DocBlock\DescriptionFactory::create
+        $body = <<<'EOT'
+        {%% for user in users %%}
+            {{ user.name }}
+        {%% endfor %%}';
+        EOT;
+
+        $expected = <<<'EOT'
+        {% for user in users %}
+            {{ user.name }}
+        {% endfor %}';
+        EOT;
+
+        $fixture = new Description($body, []);
+
+        $this->assertSame($expected, (string) $fixture);
+    }
 }
diff --git a/tests/unit/DocBlock/ExampleFinderTest.php b/tests/unit/DocBlock/ExampleFinderTest.php
index c45337cb90dd18e034c722a54d7f68bc3ddf42b6..6bc17ec43c9154cee2a7266817bd1f0c5df58ab1 100644
--- a/tests/unit/DocBlock/ExampleFinderTest.php
+++ b/tests/unit/DocBlock/ExampleFinderTest.php
@@ -14,8 +14,7 @@ use PHPUnit\Framework\TestCase;
  */
 class ExampleFinderTest extends TestCase
 {
-    /** @var ExampleFinder */
-    private $fixture;
+    private ExampleFinder $fixture;
 
     /**
      * Call Mockery::close after each test.
diff --git a/tests/unit/DocBlock/StandardTagFactoryTest.php b/tests/unit/DocBlock/StandardTagFactoryTest.php
index 2e380d9186c91b73efe6db8a6e6b787360d3ec57..5a954d5247da4aeb42f0e7cd573f0d3c79331dc1 100644
--- a/tests/unit/DocBlock/StandardTagFactoryTest.php
+++ b/tests/unit/DocBlock/StandardTagFactoryTest.php
@@ -18,6 +18,7 @@ use Mockery as m;
 use phpDocumentor\Reflection\Assets\CustomParam;
 use phpDocumentor\Reflection\Assets\CustomServiceClass;
 use phpDocumentor\Reflection\Assets\CustomServiceInterface;
+use phpDocumentor\Reflection\Assets\CustomTagFactory;
 use phpDocumentor\Reflection\DocBlock\Tags\Author;
 use phpDocumentor\Reflection\DocBlock\Tags\Formatter;
 use phpDocumentor\Reflection\DocBlock\Tags\Formatter\PassthroughFormatter;
@@ -225,6 +226,22 @@ class StandardTagFactoryTest extends TestCase
         $this->assertSame('author', $tag->getName());
     }
 
+    public function testTagWithHandlerObject(): void
+    {
+        $fqsenResolver = new FqsenResolver();
+
+        $customFactory = new CustomTagFactory();
+        $injectedClass = new CustomServiceClass();
+
+        $tagFactory = new StandardTagFactory($fqsenResolver);
+        $tagFactory->addService($injectedClass);
+        $tagFactory->registerTagHandler('param', $customFactory);
+        $tag = $tagFactory->create('@param foo');
+
+        self::assertSame('custom', $tag->getName());
+        self::assertSame($injectedClass, $customFactory->class);
+    }
+
     /**
      * @uses \phpDocumentor\Reflection\DocBlock\StandardTagFactory::addService
      * @uses \phpDocumentor\Reflection\DocBlock\Tags\Author
diff --git a/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..59f148db1c0d269df1eb8f03b1c88f98616498b9
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/MethodFactoryTest.php
@@ -0,0 +1,163 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Method;
+use phpDocumentor\Reflection\DocBlock\Tags\MethodParameter;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\String_;
+use phpDocumentor\Reflection\Types\Void_;
+
+final class MethodFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\MethodFactory::supports
+     * @dataProvider tagProvider
+     */
+    public function testIsCreated(string $tagLine, Method $tag): void
+    {
+        $ast = $this->parseTag($tagLine);
+        $factory = new MethodFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            $tag,
+            $factory->create($ast, $context)
+        );
+    }
+
+    /** @return array<array<string|Method>> */
+    public function tagProvider(): array
+    {
+        return [
+            [
+                '@method static string myMethod()',
+                new Method(
+                    'myMethod',
+                    [],
+                    new String_(),
+                    true,
+                    new Description(''),
+                    false,
+                    []
+                ),
+            ],
+            [
+                '@method string myMethod()',
+                new Method(
+                    'myMethod',
+                    [],
+                    new String_(),
+                    false,
+                    new Description(''),
+                    false,
+                    []
+                ),
+            ],
+            [
+                '@method myMethod()',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    []
+                ),
+            ],
+            [
+                '@method myMethod($a)',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [new MethodParameter('a', new Mixed_())]
+                ),
+            ],
+            [
+                '@method void setInteger(integer $integer)',
+                new Method(
+                    'setInteger',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [new MethodParameter('integer', new Integer())]
+                ),
+            ],
+            [
+                '@method myMethod($a = 1)',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [new MethodParameter('a', new Mixed_(), false, false, '1')]
+                ),
+            ],
+            [
+                '@method myMethod(int $a = 1)',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [new MethodParameter('a', new Integer(), false, false, '1')]
+                ),
+            ],
+            [
+                '@method myMethod(int ...$a)',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [new MethodParameter('a', new Integer(), false, true)]
+                ),
+            ],
+            [
+                '@method myMethod(int &$a, string $b)',
+                new Method(
+                    'myMethod',
+                    [],
+                    new Void_(),
+                    false,
+                    new Description(''),
+                    false,
+                    [
+                        new MethodParameter('a', new Integer(), true, false),
+                        new MethodParameter('b', new String_(), false, false),
+                    ]
+                ),
+            ],
+        ];
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5c50181c75848e4a89a63a5a623597049971b436
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/ParamFactoryTest.php
@@ -0,0 +1,133 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tag;
+use phpDocumentor\Reflection\DocBlock\Tags\InvalidTag;
+use phpDocumentor\Reflection\DocBlock\Tags\Param;
+use phpDocumentor\Reflection\Fqsen;
+use phpDocumentor\Reflection\PseudoTypes\IntegerValue;
+use phpDocumentor\Reflection\PseudoTypes\StringValue;
+use phpDocumentor\Reflection\Types\Compound;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\Integer;
+use phpDocumentor\Reflection\Types\Mixed_;
+use phpDocumentor\Reflection\Types\Object_;
+use phpDocumentor\Reflection\Types\String_;
+
+final class ParamFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ParamFactory::supports
+     * @dataProvider paramInputProvider
+     */
+    public function testParamIsCreated(string $input, Tag $expected): void
+    {
+        $ast = $this->parseTag($input);
+        $factory = new ParamFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            $expected,
+            $factory->create($ast, $context)
+        );
+    }
+
+    /**
+     * @return array<array-key, string|Param>
+     */
+    public function paramInputProvider(): array
+    {
+        return [
+            [
+                '@param string $var',
+                new Param(
+                    'var',
+                    new String_(),
+                    false,
+                    new Description(''),
+                    false
+                ),
+            ],
+            [
+                '@param $param8 Description 4',
+                new Param(
+                    'param8',
+                    new Mixed_(),
+                    false,
+                    new Description('Description 4'),
+                    false
+                ),
+            ],
+            [
+                '@param $param9',
+                new Param(
+                    'param9',
+                    new Mixed_(),
+                    false,
+                    new Description(''),
+                    false
+                ),
+            ],
+            [
+                '@param int My Description',
+                new Param(
+                    null,
+                    new Integer(),
+                    false,
+                    new Description('My Description'),
+                    false
+                ),
+            ],
+            [
+                '@param \'GET\'|SomeClass $arg My Description',
+                new Param(
+                    'arg',
+                    new Compound(
+                        [
+                            new StringValue('GET'),
+                            new Object_(new Fqsen('\SomeClass')),
+                        ]
+                    ),
+                    false,
+                    new Description('My Description'),
+                    false
+                ),
+            ],
+            [
+                '@param 8|SomeClass $arg My Description',
+                new Param(
+                    'arg',
+                    new Compound(
+                        [
+                            new IntegerValue(8),
+                            new Object_(new Fqsen('\SomeClass')),
+                        ]
+                    ),
+                    false,
+                    new Description('My Description'),
+                    false
+                ),
+            ],
+            [
+                '@param array[\Illuminate\Notifications\Channels\Notification] $notification',
+                InvalidTag::create('array[\Illuminate\Notifications\Channels\Notification] $notification', 'param'),
+            ],
+        ];
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..738275cbc831beecb20501dc17939de11310c66e
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Property;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyFactory::supports
+     */
+    public function testParamIsCreated(): void
+    {
+        $ast = $this->parseTag('@property string $var');
+        $factory = new PropertyFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            new Property(
+                'var',
+                new String_(),
+                new Description('')
+            ),
+            $factory->create($ast, $context)
+        );
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..40fd1226854e12c6f422291c1056a4136cec3978
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyReadFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyRead;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyReadFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyReadFactory::supports
+     */
+    public function testParamIsCreated(): void
+    {
+        $ast = $this->parseTag('@property-read string $var');
+        $factory = new PropertyReadFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            new PropertyRead(
+                'var',
+                new String_(),
+                new Description('')
+            ),
+            $factory->create($ast, $context)
+        );
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..0f3e239d1729dcfa6f879f0d524b7338697ad02c
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/PropertyWriteFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\PropertyWrite;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class PropertyWriteFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\PropertyWriteFactory::supports
+     */
+    public function testParamIsCreated(): void
+    {
+        $ast = $this->parseTag('@property-write string $var');
+        $factory = new PropertyWriteFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            new PropertyWrite(
+                'var',
+                new String_(),
+                new Description('')
+            ),
+            $factory->create($ast, $context)
+        );
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..5b664cc34c667575d804c42151afaca60cfe15f9
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/ReturnFactoryTest.php
@@ -0,0 +1,43 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Return_;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class ReturnFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\ReturnFactory::supports
+     */
+    public function testParamIsCreated(): void
+    {
+        $ast = $this->parseTag('@return string');
+        $factory = new ReturnFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            new Return_(
+                new String_(),
+                new Description('')
+            ),
+            $factory->create($ast, $context)
+        );
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php
new file mode 100644
index 0000000000000000000000000000000000000000..ec9056541747466d86834c3ed5acad55d3e9b135
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/TagFactoryTestCase.php
@@ -0,0 +1,62 @@
+<?php
+/*
+ * This file is part of phpDocumentor.
+ *
+ *  For the full copyright and license information, please view the LICENSE
+ *  file that was distributed with this source code.
+ *
+ *  @link      http://phpdoc.org
+ *
+ */
+
+declare(strict_types=1);
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use Mockery as m;
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\DescriptionFactory;
+use phpDocumentor\Reflection\FqsenResolver;
+use phpDocumentor\Reflection\TypeResolver;
+use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
+use PHPStan\PhpDocParser\Lexer\Lexer;
+use PHPStan\PhpDocParser\Parser\ConstExprParser;
+use PHPStan\PhpDocParser\Parser\PhpDocParser;
+use PHPStan\PhpDocParser\Parser\TokenIterator;
+use PHPStan\PhpDocParser\Parser\TypeParser;
+use PHPUnit\Framework\TestCase;
+
+abstract class TagFactoryTestCase extends TestCase
+{
+    public function parseTag(string $tag): PhpDocTagNode
+    {
+        $lexer = new Lexer();
+        $tokens = $lexer->tokenize($tag);
+        $constParser = new ConstExprParser();
+
+        return (new PhpDocParser(new TypeParser($constParser), $constParser))->parseTag(new TokenIterator($tokens));
+    }
+
+    public function giveTypeResolver(): TypeResolver
+    {
+        return new TypeResolver(new FqsenResolver());
+    }
+
+    public function givenDescriptionFactory(): DescriptionFactory
+    {
+        $factory =  m::mock(DescriptionFactory::class);
+        $factory->shouldReceive('create')->andReturnUsing(static fn ($args) => new Description($args));
+
+        return $factory;
+    }
+
+    /**
+     * Call Mockery::close after each test.
+     *
+     * @after
+     */
+    public function closeMockery(): void
+    {
+        m::close();
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..61f22dfdd4a1b583a81fd3bef6d824bdd97a8a1a
--- /dev/null
+++ b/tests/unit/DocBlock/Tags/Factory/VarFactoryTest.php
@@ -0,0 +1,44 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * This file is part of phpDocumentor.
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ *
+ * @link      http://phpdoc.org
+ */
+
+namespace phpDocumentor\Reflection\DocBlock\Tags\Factory;
+
+use phpDocumentor\Reflection\DocBlock\Description;
+use phpDocumentor\Reflection\DocBlock\Tags\Var_;
+use phpDocumentor\Reflection\Types\Context;
+use phpDocumentor\Reflection\Types\String_;
+
+final class VarFactoryTest extends TagFactoryTestCase
+{
+    /**
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::__construct
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::create
+     * @covers \phpDocumentor\Reflection\DocBlock\Tags\Factory\VarFactory::supports
+     */
+    public function testVarIsCreated(): void
+    {
+        $ast = $this->parseTag('@var string $var');
+        $factory = new VarFactory($this->giveTypeResolver(), $this->givenDescriptionFactory());
+        $context = new Context('global');
+
+        self::assertTrue($factory->supports($ast, $context));
+        self::assertEquals(
+            new Var_(
+                'var',
+                new String_(),
+                new Description('')
+            ),
+            $factory->create($ast, $context)
+        );
+    }
+}
diff --git a/tests/unit/DocBlock/Tags/MethodTest.php b/tests/unit/DocBlock/Tags/MethodTest.php
index 1f068dbb10d07bd85fe7f513b43057b95e673920..dfc0032bc0e807068eab7d3052cc9f511c9de7f1 100644
--- a/tests/unit/DocBlock/Tags/MethodTest.php
+++ b/tests/unit/DocBlock/Tags/MethodTest.php
@@ -339,6 +339,7 @@ class MethodTest extends TestCase
         $this->assertEquals($expectedArguments, $fixture->getArguments());
         $this->assertInstanceOf(Void_::class, $fixture->getReturnType());
         $this->assertSame($description, $fixture->getDescription());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -370,6 +371,7 @@ class MethodTest extends TestCase
         $this->assertSame('static $this myMethod()', (string) $fixture);
         $this->assertSame('myMethod', $fixture->getMethodName());
         $this->assertInstanceOf(This::class, $fixture->getReturnType());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -401,6 +403,7 @@ class MethodTest extends TestCase
         $this->assertSame('void myVeryLongMethodName(mixed $node)', (string) $fixture);
         $this->assertSame('myVeryLongMethodName', $fixture->getMethodName());
         $this->assertInstanceOf(Void_::class, $fixture->getReturnType());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -542,6 +545,7 @@ class MethodTest extends TestCase
         $this->assertEquals([], $fixture->getArguments());
         $this->assertInstanceOf(Void_::class, $fixture->getReturnType());
         $this->assertSame($description, $fixture->getDescription());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -578,6 +582,7 @@ class MethodTest extends TestCase
         $this->assertEquals([], $fixture->getArguments());
         $this->assertInstanceOf(Void_::class, $fixture->getReturnType());
         $this->assertSame($description, $fixture->getDescription());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -613,6 +618,7 @@ class MethodTest extends TestCase
         $this->assertEquals([], $fixture->getArguments());
         $this->assertInstanceOf(Void_::class, $fixture->getReturnType());
         $this->assertSame($description, $fixture->getDescription());
+        $this->assertFalse($fixture->returnsReference());
     }
 
     /**
@@ -656,4 +662,40 @@ class MethodTest extends TestCase
             $fixture->getReturnType()
         );
     }
+
+    /**
+     * @uses \phpDocumentor\Reflection\DocBlock\Tags\Method::<public>
+     * @uses \phpDocumentor\Reflection\DocBlock\DescriptionFactory
+     * @uses \phpDocumentor\Reflection\TypeResolver
+     * @uses \phpDocumentor\Reflection\DocBlock\Description
+     * @uses \phpDocumentor\Reflection\Fqsen
+     * @uses \phpDocumentor\Reflection\Types\Context
+     * @uses \phpDocumentor\Reflection\Types\String_
+     *
+     * @covers ::create
+     */
+    public function testCreateWithReference(): void
+    {
+        $descriptionFactory = m::mock(DescriptionFactory::class);
+        $resolver           = new TypeResolver();
+        $context            = new Context('');
+
+        $description = new Description('');
+
+        $descriptionFactory->shouldReceive('create')->with('', $context)->andReturn($description);
+
+        $fixture = Method::create(
+            'string &myMethod()',
+            $resolver,
+            $descriptionFactory,
+            $context
+        );
+
+        $this->assertSame('string &myMethod()', (string) $fixture);
+        $this->assertSame('myMethod', $fixture->getMethodName());
+        $this->assertEquals([], $fixture->getArguments());
+        $this->assertInstanceOf(String_::class, $fixture->getReturnType());
+        $this->assertSame($description, $fixture->getDescription());
+        $this->assertTrue($fixture->returnsReference());
+    }
 }