diff --git a/.gitignore b/.gitignore
index 9ce6c04e156d7520a0e1f9d97e9efbf30b0c9081..e72b71f24d1fd46980e7942a5ad85d2a4bd96a7f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -176,12 +176,15 @@ samples/client/petstore/python-tornado/.venv/
 
 # PHP
 samples/client/petstore/php/OpenAPIClient-php/composer.lock
+samples/client/petstore/php-dt/composer.lock
+samples/client/petstore/php-dt-modern/composer.lock
 samples/openapi3/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
 samples/server/petstore/php-laravel/lib/composer.lock
 samples/server/petstore/php-lumen/lib/composer.lock
 samples/server/petstore/php-slim4/composer.lock
 samples/server/petstore/php-symfony/SymfonyBundle-php/composer.lock
 samples/server/petstore/php-mezzio-ph/composer.lock
+samples/server/petstore/php-mezzio-ph-modern/composer.lock
 
 # ts
 samples/client/petstore/typescript-angular2/npm/npm-debug.log
diff --git a/README.md b/README.md
index 9bfd915f4390f9528d269ab848f3c656250da803..b24c159eb64f89a5309c002803e95e404f958077 100644
--- a/README.md
+++ b/README.md
@@ -76,7 +76,7 @@ OpenAPI Generator allows generation of API client libraries (SDK generation), se
 |                                  | Languages/Frameworks                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
 | -------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
 | **API clients**                  | **ActionScript**, **Ada**, **Apex**, **Bash**, **C**, **C#** (.net 2.0, 3.5 or later, .NET Standard 1.3 - 2.0, .NET Core 2.0, .NET 5.0. Libraries: RestSharp, HttpClient), **C++** (Arduino, cpp-restsdk, Qt5, Tizen, Unreal Engine 4), **Clojure**, **Crystal**, **Dart**, **Elixir**, **Elm**, **Eiffel**, **Erlang**, **Go**, **Groovy**, **Haskell** (http-client, Servant), **Java** (Jersey1.x, Jersey2.x, OkHttp, Retrofit1.x, Retrofit2.x, Feign, RestTemplate, RESTEasy, Vertx, Google API Client Library for Java, Rest-assured, Spring 5 Web Client, MicroProfile Rest Client), **k6**, **Kotlin**, **Lua**, **Nim**, **Node.js/JavaScript** (ES5, ES6, AngularJS with Google Closure Compiler annotations, Flow types, Apollo GraphQL DataStore), **Objective-C**, **OCaml**, **Perl**, **PHP**, **PowerShell**, **Python**, **R**, **Ruby**, **Rust** (hyper, reqwest, rust-server), **Scala** (akka, http4s, scalaz, sttp, swagger-async-httpclient), **Swift** (2.x, 3.x, 4.x, 5.x), **Typescript** (AngularJS, Angular (2.x - 11.x), Aurelia, Axios, Fetch, Inversify, jQuery, Nestjs, Node, redux-query, Rxjs) |
-| **Server stubs**                 | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **PHP** (Laravel, Lumen, Slim, Silex, [Symfony](https://symfony.com/), [Zend Expressive](https://github.com/zendframework/zend-expressive)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra)                                                                                                                                                                                         |
+| **Server stubs**                 | **Ada**, **C#** (ASP.NET Core, NancyFx), **C++** (Pistache, Restbed, Qt5 QHTTPEngine), **Erlang**, **F#** (Giraffe), **Go** (net/http, Gin, Echo), **Haskell** (Servant), **Java** (MSF4J, Spring, Undertow, JAX-RS: CDI, CXF, Inflector, Jersey, RestEasy, Play Framework, [PKMST](https://github.com/ProKarma-Inc/pkmst-getting-started-examples), [Vert.x](https://vertx.io/)), **Kotlin** (Spring Boot, Ktor, Vertx), **PHP** (Laravel, Lumen, [Mezzio (fka Zend Expressive)](https://github.com/mezzio/mezzio), Slim, Silex, [Symfony](https://symfony.com/)), **Python** (FastAPI, Flask), **NodeJS**, **Ruby** (Sinatra, Rails5), **Rust** (rust-server), **Scala** (Akka, [Finch](https://github.com/finagle/finch), [Lagom](https://github.com/lagom/lagom), [Play](https://www.playframework.com/), Scalatra)                                                                                                                                                                                         |
 | **API documentation generators** | **HTML**, **Confluence Wiki**, **Asciidoc**, **Markdown**, **PlantUML**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
 | **Configuration files**          | [**Apache2**](https://httpd.apache.org/)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
 | **Others**                       | **GraphQL**, **JMeter**, **Ktorm**, **MySQL Schema**, **Protocol Buffer**, **WSDL**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
@@ -902,6 +902,7 @@ Here is a list of template creators:
    * OCaml: @cgensoul
    * Perl: @wing328 [:heart:](https://www.patreon.com/wing328)
    * PHP (Guzzle): @baartosz
+   * PHP (with Data Transfer): @Articus
    * PowerShell: @beatcracker
    * PowerShell (refactored in 5.0.0): @wing328
    * Python: @spacether
@@ -960,10 +961,10 @@ Here is a list of template creators:
    * NodeJS Express: @YishTish
    * PHP Laravel: @renepardon
    * PHP Lumen: @abcsun
+   * PHP Mezzio (with Path Handler): @Articus
    * PHP Slim: @jfastnacht
    * PHP Slim4: @ybelenko
    * PHP Symfony: @ksm2
-   * PHP Zend Expressive (with Path Handler): @Articus
    * Python FastAPI: @krjakbrjak
    * Python AIOHTTP: @Jyhess
    * Ruby on Rails 5: @zlx
diff --git a/bin/configs/php-dt-modern.yaml b/bin/configs/php-dt-modern.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..33432079423a5256b449c375ef3157f3b1f516da
--- /dev/null
+++ b/bin/configs/php-dt-modern.yaml
@@ -0,0 +1,6 @@
+generatorName: php-dt
+outputDir: samples/client/petstore/php-dt-modern
+inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
+templateDir: modules/openapi-generator/src/main/resources/php-dt-modern
+additionalProperties:
+  modern: "true"
diff --git a/bin/configs/php-dt.yaml b/bin/configs/php-dt.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6e1cbcccc57e8194f8f16f3617c6a5fd674e9ba5
--- /dev/null
+++ b/bin/configs/php-dt.yaml
@@ -0,0 +1,4 @@
+generatorName: php-dt
+outputDir: samples/client/petstore/php-dt
+inputSpec: modules/openapi-generator/src/test/resources/3_0/petstore.yaml
+templateDir: modules/openapi-generator/src/main/resources/php-dt
diff --git a/docs/generators.md b/docs/generators.md
index c71da0663ed5eca6c8dbfb49b7a48cdb49abd05f..ae2927f6dce844a72c623893e163d502de7e42f2 100644
--- a/docs/generators.md
+++ b/docs/generators.md
@@ -50,6 +50,7 @@ The following generators are available:
 * [ocaml](generators/ocaml.md)  
 * [perl](generators/perl.md)  
 * [php](generators/php.md)  
+* [php-dt](generators/php-dt.md)  
 * [powershell (beta)](generators/powershell.md)  
 * [python (experimental)](generators/python.md)  
 * [python-legacy](generators/python-legacy.md)  
diff --git a/docs/generators/README.md b/docs/generators/README.md
index a8ac9c9310c31f07c7d5b28a2b72e170eed2fa4a..b9e8926f6647d7ed577556fd4c156268d4972dea 100644
--- a/docs/generators/README.md
+++ b/docs/generators/README.md
@@ -39,6 +39,7 @@ The following generators are available:
 * [ocaml](ocaml.md)  
 * [perl](perl.md)  
 * [php](php.md)  
+* [php-dt](php-dt.md)  
 * [powershell](powershell.md)  
 * [python](python.md)
 * [python-legacy](python-legacy.md)
diff --git a/docs/generators/php-dt.md b/docs/generators/php-dt.md
new file mode 100644
index 0000000000000000000000000000000000000000..0ce4ccd3debbeb067fcec681212ab64e38c0560d
--- /dev/null
+++ b/docs/generators/php-dt.md
@@ -0,0 +1,242 @@
+---
+title: Config Options for php-dt
+sidebar_label: php-dt
+---
+
+These options may be applied as additional-properties (cli) or configOptions (plugins). Refer to [configuration docs](https://openapi-generator.tech/docs/configuration) for more details.
+
+| Option | Description | Values | Default |
+| ------ | ----------- | ------ | ------- |
+|allowUnicodeIdentifiers|boolean, toggles whether unicode identifiers are allowed in names or not, default is false| |false|
+|apiPackage|package for generated api classes| |null|
+|artifactVersion|The version to use in the composer package version field. e.g. 1.2.3| |null|
+|disallowAdditionalPropertiesIfNotPresent|If false, the 'additionalProperties' implementation (set to true by default) is compliant with the OAS and JSON schema specifications. If true (default), keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.|<dl><dt>**false**</dt><dd>The 'additionalProperties' implementation is compliant with the OAS and JSON schema specifications.</dd><dt>**true**</dt><dd>Keep the old (incorrect) behaviour that 'additionalProperties' is set to false by default.</dd></dl>|true|
+|ensureUniqueParams|Whether to ensure parameter names are unique in an operation (rename parameters that are not).| |true|
+|invokerPackage|The main namespace to use for all classes. e.g. Yay\Pets| |null|
+|legacyDiscriminatorBehavior|Set to false for generators with better support for discriminators. (Python, Java, Go, PowerShell, C#have this enabled by default).|<dl><dt>**true**</dt><dd>The mapping in the discriminator includes descendent schemas that allOf inherit from self and the discriminator mapping schemas in the OAS document.</dd><dt>**false**</dt><dd>The mapping in the discriminator includes any descendent schemas that allOf inherit from self, any oneOf schemas, any anyOf schemas, any x-discriminator-values, and the discriminator mapping schemas in the OAS document AND Codegen validates that oneOf and anyOf schemas contain the required discriminator and throws an error if the discriminator is missing.</dd></dl>|true|
+|modelPackage|package for generated models| |null|
+|modern|use modern language features (generated code will require PHP 8.0)| |false|
+|packageName|The main package name for classes. e.g. GeneratedPetstore| |null|
+|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
+|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
+|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
+|srcBasePath|The directory to serve as source root.| |null|
+|variableNamingConvention|naming convention of variable name, e.g. camelCase.| |snake_case|
+
+## IMPORT MAPPING
+
+| Type/Alias | Imports |
+| ---------- | ------- |
+
+
+## INSTANTIATION TYPES
+
+| Type/Alias | Instantiated By |
+| ---------- | --------------- |
+|array|array|
+|map|array|
+
+
+## LANGUAGE PRIMITIVES
+
+<ul class="column-ul">
+<li>DateTime</li>
+<li>bool</li>
+<li>boolean</li>
+<li>byte</li>
+<li>double</li>
+<li>float</li>
+<li>int</li>
+<li>integer</li>
+<li>mixed</li>
+<li>number</li>
+<li>object</li>
+<li>string</li>
+<li>void</li>
+</ul>
+
+## RESERVED WORDS
+
+<ul class="column-ul">
+<li>__halt_compiler</li>
+<li>_header_accept</li>
+<li>_tempbody</li>
+<li>abstract</li>
+<li>and</li>
+<li>array</li>
+<li>as</li>
+<li>break</li>
+<li>callable</li>
+<li>case</li>
+<li>catch</li>
+<li>class</li>
+<li>clone</li>
+<li>const</li>
+<li>continue</li>
+<li>declare</li>
+<li>default</li>
+<li>die</li>
+<li>do</li>
+<li>echo</li>
+<li>else</li>
+<li>elseif</li>
+<li>empty</li>
+<li>enddeclare</li>
+<li>endfor</li>
+<li>endforeach</li>
+<li>endif</li>
+<li>endswitch</li>
+<li>endwhile</li>
+<li>eval</li>
+<li>exit</li>
+<li>extends</li>
+<li>final</li>
+<li>for</li>
+<li>foreach</li>
+<li>formparams</li>
+<li>function</li>
+<li>global</li>
+<li>goto</li>
+<li>headerparams</li>
+<li>httpbody</li>
+<li>if</li>
+<li>implements</li>
+<li>include</li>
+<li>include_once</li>
+<li>instanceof</li>
+<li>insteadof</li>
+<li>interface</li>
+<li>isset</li>
+<li>list</li>
+<li>namespace</li>
+<li>new</li>
+<li>or</li>
+<li>print</li>
+<li>private</li>
+<li>protected</li>
+<li>public</li>
+<li>queryparams</li>
+<li>require</li>
+<li>require_once</li>
+<li>resourcepath</li>
+<li>return</li>
+<li>static</li>
+<li>switch</li>
+<li>throw</li>
+<li>trait</li>
+<li>try</li>
+<li>unset</li>
+<li>use</li>
+<li>var</li>
+<li>while</li>
+<li>xor</li>
+</ul>
+
+## FEATURE SET
+
+
+### Client Modification Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|BasePath|✗|ToolingExtension
+|Authorizations|✗|ToolingExtension
+|UserAgent|✗|ToolingExtension
+|MockServer|✗|ToolingExtension
+
+### Data Type Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|Custom|✗|OAS2,OAS3
+|Int32|✓|OAS2,OAS3
+|Int64|✓|OAS2,OAS3
+|Float|✓|OAS2,OAS3
+|Double|✓|OAS2,OAS3
+|Decimal|✓|ToolingExtension
+|String|✓|OAS2,OAS3
+|Byte|✓|OAS2,OAS3
+|Binary|✓|OAS2,OAS3
+|Boolean|✓|OAS2,OAS3
+|Date|✓|OAS2,OAS3
+|DateTime|✓|OAS2,OAS3
+|Password|✓|OAS2,OAS3
+|File|✓|OAS2
+|Array|✓|OAS2,OAS3
+|Maps|✓|ToolingExtension
+|CollectionFormat|✓|OAS2
+|CollectionFormatMulti|✓|OAS2
+|Enum|✓|OAS2,OAS3
+|ArrayOfEnum|✓|ToolingExtension
+|ArrayOfModel|✓|ToolingExtension
+|ArrayOfCollectionOfPrimitives|✓|ToolingExtension
+|ArrayOfCollectionOfModel|✓|ToolingExtension
+|ArrayOfCollectionOfEnum|✓|ToolingExtension
+|MapOfEnum|✓|ToolingExtension
+|MapOfModel|✓|ToolingExtension
+|MapOfCollectionOfPrimitives|✓|ToolingExtension
+|MapOfCollectionOfModel|✓|ToolingExtension
+|MapOfCollectionOfEnum|✓|ToolingExtension
+
+### Documentation Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|Readme|✓|ToolingExtension
+|Model|✓|ToolingExtension
+|Api|✓|ToolingExtension
+
+### Global Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|Host|✓|OAS2,OAS3
+|BasePath|✓|OAS2,OAS3
+|Info|✓|OAS2,OAS3
+|Schemes|✗|OAS2,OAS3
+|PartialSchemes|✓|OAS2,OAS3
+|Consumes|✓|OAS2
+|Produces|✓|OAS2
+|ExternalDocumentation|✓|OAS2,OAS3
+|Examples|✓|OAS2,OAS3
+|XMLStructureDefinitions|✗|OAS2,OAS3
+|MultiServer|✗|OAS3
+|ParameterizedServer|✗|OAS3
+|ParameterStyling|✗|OAS3
+|Callbacks|✗|OAS3
+|LinkObjects|✗|OAS3
+
+### Parameter Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|Path|✓|OAS2,OAS3
+|Query|✓|OAS2,OAS3
+|Header|✓|OAS2,OAS3
+|Body|✓|OAS2
+|FormUnencoded|✓|OAS2
+|FormMultipart|✓|OAS2
+|Cookie|✓|OAS3
+
+### Schema Support Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|Simple|✓|OAS2,OAS3
+|Composite|✓|OAS2,OAS3
+|Polymorphism|✗|OAS2,OAS3
+|Union|✗|OAS3
+
+### Security Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|BasicAuth|✗|OAS2,OAS3
+|ApiKey|✗|OAS2,OAS3
+|OpenIDConnect|✗|OAS3
+|BearerToken|✗|OAS3
+|OAuth2_Implicit|✗|OAS2,OAS3
+|OAuth2_Password|✗|OAS2,OAS3
+|OAuth2_ClientCredentials|✗|OAS2,OAS3
+|OAuth2_AuthorizationCode|✗|OAS2,OAS3
+
+### Wire Format Feature
+| Name | Supported | Defined By |
+| ---- | --------- | ---------- |
+|JSON|✓|OAS2,OAS3
+|XML|✗|OAS2,OAS3
+|PROTOBUF|✗|ToolingExtension
+|Custom|✗|OAS2,OAS3
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpDataTransferClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpDataTransferClientCodegen.java
new file mode 100644
index 0000000000000000000000000000000000000000..e85f3b67da4fcac31ff4491576d13e5129a919d5
--- /dev/null
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/PhpDataTransferClientCodegen.java
@@ -0,0 +1,444 @@
+/*
+ * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
+ * Copyright 2018 SmartBear Software
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openapitools.codegen.languages;
+
+import io.swagger.v3.oas.models.OpenAPI;
+import io.swagger.v3.oas.models.Operation;
+import io.swagger.v3.oas.models.PathItem;
+import io.swagger.v3.oas.models.PathItem.HttpMethod;
+import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.media.*;
+import io.swagger.v3.oas.models.parameters.Parameter;
+import io.swagger.v3.oas.models.parameters.RequestBody;
+import io.swagger.v3.oas.models.responses.ApiResponse;
+import io.swagger.v3.oas.models.responses.ApiResponses;
+import org.openapitools.codegen.*;
+import org.openapitools.codegen.meta.features.*;
+import org.openapitools.codegen.utils.ModelUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.*;
+
+public class PhpDataTransferClientCodegen extends AbstractPhpCodegen {
+    private final Logger LOGGER = LoggerFactory.getLogger(PhpDataTransferClientCodegen.class);
+    // Custom generator option names
+    public static final String OPT_MODERN = "modern";
+    // Internal vendor extension names for extra template data that should not be set in specification
+    public static final String VEN_PARAMETER_LOCATION = "internal.parameterLocation";
+    public static final String VEN_FROM_PARAMETERS = "internal.fromParameters";
+    public static final String VEN_COLLECTION_FORMAT = "internal.collectionFormat";
+    public static final String VEN_PARAMETER_DATA_TYPE = "internal.parameterDataType";
+    public static final String VEN_HAS_PARAMETER_DATA = "internal.hasParameterData";
+    public static final String VEN_FROM_CONTAINER = "internal.fromContainer";
+    public static final String VEN_CONTAINER_DATA_TYPE = "internal.containerDataType";
+
+    private boolean useModernSyntax = false;
+
+    @Override
+    public CodegenType getTag() {
+        return CodegenType.CLIENT;
+    }
+
+    @Override
+    public String getName() {
+        return "php-dt";
+    }
+
+    @Override
+    public String getHelp() {
+        return "Generates PHP client relying on Data Transfer ( https://github.com/Articus/DataTransfer ) and compliant with PSR-7, PSR-11, PSR-17 and PSR-18.";
+    }
+
+    public PhpDataTransferClientCodegen() {
+        super();
+        modifyFeatureSet(features -> features
+                .includeDocumentationFeatures(DocumentationFeature.Readme)
+                .wireFormatFeatures(EnumSet.of(WireFormatFeature.JSON))
+                .securityFeatures(EnumSet.noneOf(SecurityFeature.class))
+                .excludeGlobalFeatures(
+                        GlobalFeature.XMLStructureDefinitions,
+                        GlobalFeature.Callbacks,
+                        GlobalFeature.LinkObjects,
+                        GlobalFeature.ParameterStyling
+                )
+                .excludeSchemaSupportFeatures(
+                        SchemaSupportFeature.Polymorphism
+                )
+        );
+
+        //no point to use double - http://php.net/manual/en/language.types.float.php , especially because of PHP 7+ float type declaration
+        typeMapping.put("double", "float");
+
+        apiTemplateFiles.clear();
+        apiTestTemplateFiles.clear();
+        apiDocTemplateFiles.clear();
+        modelTestTemplateFiles.clear();
+        modelDocTemplateFiles.clear();
+
+        additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, "1.0.0");
+        //Register custom CLI options
+        addSwitch(OPT_MODERN, "use modern language features (generated code will require PHP 8.0)", useModernSyntax);
+    }
+
+    @Override
+    public void processOpts() {
+        setSrcBasePath("src");
+        //Preserve and process options mangled in parent class
+        String rootNamespace = "App";
+        if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
+            rootNamespace = (String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE);
+        }
+        String modelNamespace = rootNamespace + "\\DTO";
+        if (additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
+            modelNamespace = (String) additionalProperties.get(CodegenConstants.MODEL_PACKAGE);
+        }
+        super.processOpts();
+        //Restore mangled options
+        setInvokerPackage(rootNamespace);
+        additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, rootNamespace);
+        setModelPackage(modelNamespace);
+        additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelNamespace);
+        //Process custom options
+        if (additionalProperties.containsKey(OPT_MODERN)) {
+            embeddedTemplateDir = templateDir = "php-dt-modern";
+            useModernSyntax = true;
+        } else {
+            embeddedTemplateDir = templateDir = "php-dt";
+        }
+
+        supportingFiles.add(new SupportingFile("composer.json.mustache", "", "composer.json"));
+        supportingFiles.add(new SupportingFile("ApiClient.php.mustache", toSrcPath(invokerPackage, srcBasePath), "ApiClient.php"));
+        supportingFiles.add(new SupportingFile("ApiClientFactory.php.mustache", toSrcPath(invokerPackage, srcBasePath), "ApiClientFactory.php"));
+        supportingFiles.add(new SupportingFile("README.md.mustache", "", "README.md"));
+    }
+
+    @Override
+    public String toSrcPath(String packageName, String basePath) {
+        return basePath + File.separator + packageName.replace("\\", File.separator);
+    }
+
+    @Override
+    public String toApiName(String name) {
+        return super.toApiName(toModelName(name));
+    }
+
+    @Override
+    public String getTypeDeclaration(Schema p) {
+        String result;
+        Map<String, Object> extensions = p.getExtensions();
+        if ((extensions != null) && extensions.containsKey(VEN_CONTAINER_DATA_TYPE)) {
+            result = (String) extensions.get(VEN_CONTAINER_DATA_TYPE);
+        } else if (useModernSyntax && (ModelUtils.isArraySchema(p) || ModelUtils.isMapSchema(p))) {
+            result = "array";
+        } else {
+            result = super.getTypeDeclaration(p);
+        }
+        return result;
+    }
+
+    @Override
+    public void addOperationToGroup(String tag, String resourcePath, Operation operation, CodegenOperation co, Map<String, List<CodegenOperation>> operations) {
+        //Do not use tags for operation grouping
+        super.addOperationToGroup("", resourcePath, operation, co, operations);
+    }
+
+    @Override
+    protected String getContentType(RequestBody requestBody) {
+        //Awfully nasty workaround to skip formParams generation
+        return null;
+    }
+
+    @Override
+    public void preprocessOpenAPI(OpenAPI openAPI) {
+        super.preprocessOpenAPI(openAPI);
+
+        generateParameterSchemas(openAPI);
+        generateContainerSchemas(openAPI);
+    }
+
+    @Override
+    public void processOpenAPI(OpenAPI openAPI) {
+        super.processOpenAPI(openAPI);
+
+        quoteMediaTypes(openAPI);
+    }
+
+    /**
+     * Generate additional model definitions from query parameters
+     *
+     * @param openAPI OpenAPI object
+     */
+    protected void generateParameterSchemas(OpenAPI openAPI) {
+        Map<String, PathItem> paths = openAPI.getPaths();
+        if (paths != null) {
+            for (String pathname : paths.keySet()) {
+                PathItem path = paths.get(pathname);
+                Map<HttpMethod, Operation> operationMap = path.readOperationsMap();
+                if (operationMap != null) {
+                    for (HttpMethod method : operationMap.keySet()) {
+                        Operation operation = operationMap.get(method);
+                        Map<String, Schema> propertySchemas = new HashMap<>();
+                        if (operation == null || operation.getParameters() == null) {
+                            continue;
+                        }
+
+                        List<String> requiredProperties = new ArrayList<>();
+                        for (Parameter parameter : operation.getParameters()) {
+                            Parameter referencedParameter = ModelUtils.getReferencedParameter(openAPI, parameter);
+                            Schema propertySchema = convertParameterToSchema(openAPI, referencedParameter);
+                            if (propertySchema != null) {
+                                propertySchemas.put(propertySchema.getName(), propertySchema);
+                                if (Boolean.TRUE.equals(referencedParameter.getRequired())) {
+                                    requiredProperties.add(propertySchema.getName());
+                                }
+                            }
+                        }
+
+                        if (!propertySchemas.isEmpty()) {
+                            ObjectSchema schema = new ObjectSchema();
+                            String operationId = getOrGenerateOperationId(operation, pathname, method.name());
+                            schema.setDescription("Parameters for " + operationId);
+                            schema.setProperties(propertySchemas);
+                            schema.setRequired(requiredProperties);
+                            addInternalExtensionToSchema(schema, VEN_FROM_PARAMETERS, Boolean.TRUE);
+                            String schemaName = generateUniqueSchemaName(openAPI, operationId + "ParameterData");
+                            openAPI.getComponents().addSchemas(schemaName, schema);
+                            String schemaDataType = getTypeDeclaration(toModelName(schemaName));
+                            addInternalExtensionToOperation(operation, VEN_PARAMETER_DATA_TYPE, schemaDataType);
+                            addInternalExtensionToOperation(operation, VEN_HAS_PARAMETER_DATA, Boolean.TRUE);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    protected Schema convertParameterToSchema(OpenAPI openAPI, Parameter parameter) {
+        Schema property = null;
+
+        Schema parameterSchema = ModelUtils.getReferencedSchema(openAPI, parameter.getSchema());
+        // array
+        if (ModelUtils.isArraySchema(parameterSchema)) {
+            Schema itemSchema = ((ArraySchema) parameterSchema).getItems();
+            ArraySchema arraySchema = new ArraySchema();
+            arraySchema.setMinItems(parameterSchema.getMinItems());
+            arraySchema.setMaxItems(parameterSchema.getMaxItems());
+            arraySchema.setItems(itemSchema);
+            String collectionFormat = getCollectionFormat(parameter);
+            if (collectionFormat == null) {
+                collectionFormat = "csv";
+            }
+            addInternalExtensionToSchema(arraySchema, VEN_COLLECTION_FORMAT, collectionFormat);
+            property = arraySchema;
+        } else { // non-array e.g. string, integer
+            switch (parameterSchema.getType()) {
+                case "string":
+                    StringSchema stringSchema = new StringSchema();
+                    stringSchema.setMinLength(parameterSchema.getMinLength());
+                    stringSchema.setMaxLength(parameterSchema.getMaxLength());
+                    stringSchema.setPattern(parameterSchema.getPattern());
+                    stringSchema.setEnum(parameterSchema.getEnum());
+                    property = stringSchema;
+                    break;
+                case "integer":
+                    IntegerSchema integerSchema = new IntegerSchema();
+                    integerSchema.setMinimum(parameterSchema.getMinimum());
+                    integerSchema.setMaximum(parameterSchema.getMaximum());
+                    property = integerSchema;
+                    break;
+                case "number":
+                    NumberSchema floatSchema = new NumberSchema();
+                    floatSchema.setMinimum(parameterSchema.getMinimum());
+                    floatSchema.setMaximum(parameterSchema.getMaximum());
+                    property = floatSchema;
+                    break;
+                case "boolean":
+                    property = new BooleanSchema();
+                    break;
+                case "date":
+                    property = new DateSchema();
+                    break;
+                case "date-time":
+                    property = new DateTimeSchema();
+                    break;
+            }
+        }
+
+        if (property != null) {
+            property.setName(parameter.getName());
+            property.setDescription(parameter.getDescription());
+            addInternalExtensionToSchema(property, VEN_PARAMETER_LOCATION, parameter.getIn());
+        }
+        return property;
+    }
+
+    protected void addInternalExtensionToSchema(Schema schema, String name, Object value) {
+        //Add internal extension directly, because addExtension filters extension names
+        if (schema.getExtensions() == null) {
+            schema.setExtensions(new HashMap<>());
+        }
+        schema.getExtensions().put(name, value);
+    }
+
+    protected void addInternalExtensionToOperation(Operation operation, String name, Object value) {
+        //Add internal extension directly, because addExtension filters extension names
+        if (operation.getExtensions() == null) {
+            operation.setExtensions(new HashMap<>());
+        }
+        operation.getExtensions().put(name, value);
+    }
+
+    protected String generateUniqueSchemaName(OpenAPI openAPI, String name) {
+        String result = name;
+        if (openAPI.getComponents().getSchemas() != null) {
+            int count = 1;
+            while (openAPI.getComponents().getSchemas().containsKey(result)) {
+                result = name + "_" + count;
+                count += 1;
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Generate additional model definitions for containers in whole specification
+     *
+     * @param openAPI OpenAPI object
+     */
+    protected void generateContainerSchemas(OpenAPI openAPI) {
+        Paths paths = openAPI.getPaths();
+        for (String pathName : paths.keySet()) {
+            for (Operation operation : paths.get(pathName).readOperations()) {
+                List<Parameter> parameters = operation.getParameters();
+                if (parameters != null) {
+                    for (Parameter parameter : parameters) {
+                        generateContainerSchemas(openAPI, ModelUtils.getReferencedParameter(openAPI, parameter).getSchema());
+                    }
+                }
+                RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
+                if (requestBody != null) {
+                    Content requestBodyContent = requestBody.getContent();
+                    if (requestBodyContent != null) {
+                        for (String mediaTypeName : requestBodyContent.keySet()) {
+                            generateContainerSchemas(openAPI, requestBodyContent.get(mediaTypeName).getSchema());
+                        }
+                    }
+                }
+                ApiResponses responses = operation.getResponses();
+                for (String responseCode : responses.keySet()) {
+                    ApiResponse response = ModelUtils.getReferencedApiResponse(openAPI, responses.get(responseCode));
+                    Content responseContent = response.getContent();
+                    if (responseContent != null) {
+                        for (String mediaTypeName : responseContent.keySet()) {
+                            generateContainerSchemas(openAPI, responseContent.get(mediaTypeName).getSchema());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Generate additional model definitions for containers in specified schema
+     *
+     * @param openAPI OpenAPI object
+     * @param schema OAS schema to process
+     */
+    protected void generateContainerSchemas(OpenAPI openAPI, Schema schema) {
+        if (schema != null) {
+            //Dereference schema
+            schema = ModelUtils.getReferencedSchema(openAPI, schema);
+            Boolean isContainer = Boolean.FALSE;
+
+            if (ModelUtils.isObjectSchema(schema)) {
+                //Recursively process all schemas of object properties
+                Map<String, Schema> properties = schema.getProperties();
+                if (properties != null) {
+                    for (String propertyName: properties.keySet()) {
+                        generateContainerSchemas(openAPI, properties.get(propertyName));
+                    }
+                }
+            } else if (ModelUtils.isArraySchema(schema)) {
+                //Recursively process schema of array items
+                generateContainerSchemas(openAPI, ((ArraySchema) schema).getItems());
+                isContainer = Boolean.TRUE;
+            } else if (ModelUtils.isMapSchema(schema)) {
+                //Recursively process schema of map items
+                Object itemSchema = schema.getAdditionalProperties();
+                if (itemSchema instanceof Schema) {
+                    generateContainerSchemas(openAPI, (Schema) itemSchema);
+                }
+                isContainer = Boolean.TRUE;
+            }
+
+            if (isContainer) {
+                //Generate special component schema for container
+                String containerSchemaName = generateUniqueSchemaName(openAPI, "Collection");
+                Schema containerSchema = new ObjectSchema();
+                containerSchema.addProperties("inner", schema);
+                addInternalExtensionToSchema(containerSchema, VEN_FROM_CONTAINER, Boolean.TRUE);
+                openAPI.getComponents().addSchemas(containerSchemaName, containerSchema);
+                String containerDataType = getTypeDeclaration(toModelName(containerSchemaName));
+                addInternalExtensionToSchema(schema, VEN_CONTAINER_DATA_TYPE, containerDataType);
+            }
+        }
+    }
+
+    /**
+     * Awfully nasty workaround - add quotation marks for all media types to prevent special treatment of form media types
+     * in org/openapitools/codegen/DefaultGenerator.java:873
+     * TODO find a better way to prevent special form media type treatment
+     *
+     * @param openAPI OpenAPI object
+     */
+    protected void quoteMediaTypes(OpenAPI openAPI) {
+        Map<String, PathItem> paths = openAPI.getPaths();
+        if (paths != null) {
+            for (String pathname : paths.keySet()) {
+                PathItem path = paths.get(pathname);
+                List<Operation> operations = path.readOperations();
+                if (operations != null) {
+                    for (Operation operation: operations) {
+                        RequestBody requestBody = ModelUtils.getReferencedRequestBody(openAPI, operation.getRequestBody());
+                        if (requestBody != null) {
+                            requestBody.setContent(copyWithQuotedMediaTypes(requestBody.getContent()));
+                        }
+                        ApiResponses responses = operation.getResponses();
+                        for (String responseCode : responses.keySet()) {
+                            ApiResponse response = ModelUtils.getReferencedApiResponse(openAPI, responses.get(responseCode));
+                            response.setContent(copyWithQuotedMediaTypes(response.getContent()));
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    protected Content copyWithQuotedMediaTypes(Content content) {
+        Content result = null;
+        if (content != null) {
+            result = new Content();
+            for (String mediaType: content.keySet()) {
+                result.addMediaType("'" + mediaType + "'", content.get(mediaType));
+            }
+        }
+        return result;
+    }
+}
diff --git a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
index a213327b3f7a5aa9bff33eaaf700a3b565e71413..edff28e636a0a15e1536ed96796f014c8bdc6e7e 100644
--- a/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
+++ b/modules/openapi-generator/src/main/resources/META-INF/services/org.openapitools.codegen.CodegenConfig
@@ -93,6 +93,7 @@ org.openapitools.codegen.languages.PhpSlim4ServerCodegen
 org.openapitools.codegen.languages.PhpSilexServerCodegen
 org.openapitools.codegen.languages.PhpSymfonyServerCodegen
 org.openapitools.codegen.languages.PhpMezzioPathHandlerServerCodegen
+org.openapitools.codegen.languages.PhpDataTransferClientCodegen
 org.openapitools.codegen.languages.PowerShellClientCodegen
 org.openapitools.codegen.languages.ProtobufSchemaCodegen
 org.openapitools.codegen.languages.PythonLegacyClientCodegen
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClient.php.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClient.php.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..60e0d184954a34f5c7f6b14e6e4da16d68c3eb13
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClient.php.mustache
@@ -0,0 +1,123 @@
+<?php
+declare(strict_types=1);
+
+namespace {{invokerPackage}};
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+
+use Articus\DataTransfer as DT;
+use OpenAPIGenerator\APIClient as OAGAC;
+use Psr\Http\Client\ClientExceptionInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+{{#appName}}
+ * {{&appName}}
+{{/appName}}
+{{#appDescription}}
+ * {{&appDescription}}
+{{/appDescription}}
+{{#version}}
+ * The version of the OpenAPI document: {{version}}
+{{/version}}
+ */
+class ApiClient extends OAGAC\AbstractApiClient
+{
+{{#operation}}
+    //region {{operationId}}
+    /**
+{{>api_arg_doc
+}}     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function {{operationId}}Raw(
+{{>api_arg_declaration
+}}    ): ResponseInterface
+    {
+        $request = $this->createRequest('{{httpMethod}}', '{{path}}', {{#pathParams.0}}$this->getPathParameters($parameters){{/pathParams.0}}{{^pathParams.0}}[]{{/pathParams.0}}, {{#queryParams.0}}$this->getQueryParameters($parameters){{/queryParams.0}}{{^queryParams.0}}[]{{/queryParams.0}});
+{{#headerParams.0}}
+        $request = $this->addCustomHeaders($request, $parameters);
+{{/headerParams.0}}
+{{#cookieParams.0}}
+        $request = $this->addCookies($request, $parameters);
+{{/cookieParams.0}}
+{{#bodyParam}}
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+{{/bodyParam}}
+{{#hasProduces}}
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+{{/hasProduces}}
+{{#hasAuthMethods}}
+        $request = $this->addSecurity($request, $security);
+{{/hasAuthMethods}}
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+{{>api_arg_doc
+}}     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function {{operationId}}(
+{{>api_arg_declaration
+}}    ): array
+    {
+        $response = $this->{{operationId}}Raw({{>api_arg_call}});
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+{{#responses}}
+            {{#isDefault}}default{{/isDefault}}{{^isDefault}}case {{code}}{{/isDefault}}:
+{{#message}}
+                /* {{&message}} */
+{{/message}}
+{{#isModel}}
+                $responseContent = new {{dataType}}();
+{{/isModel}}
+{{^isModel}}
+{{#isArray}}
+                $responseContent = new {{dataType}}();
+{{/isArray}}
+{{/isModel}}
+{{^isModel}}
+{{^isArray}}
+{{#isMap}}
+                $responseContent = new {{dataType}}();
+{{/isMap}}
+{{/isArray}}
+{{/isModel}}
+                break;
+{{/responses}}
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+{{>api_arg_doc
+}}     * @return {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function {{operationId}}Result(
+{{>api_arg_declaration
+}}    ): {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
+    {
+        return $this->getSuccessfulContent(...$this->{{operationId}}({{>api_arg_call}}));
+    }
+    //endregion
+{{^-last}}
+
+{{/-last}}
+{{/operation}}
+}
+
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClientFactory.php.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClientFactory.php.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a36880d3d84e32525847eed8cba7e58252a23026
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/ApiClientFactory.php.mustache
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace {{invokerPackage}};
+
+use Articus\DataTransfer as DT;
+use Interop\Container\ContainerInterface;
+use OpenAPIGenerator\APIClient as OAGAC;
+
+class ApiClientFactory extends DT\ConfigAwareFactory
+{
+    public function __construct(string $configKey = ApiClient::class)
+    {
+        parent::__construct($configKey);
+    }
+
+    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
+    {
+        $config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
+        return new ApiClient(
+            $config->serverUrl,
+            $container->get($config->dataTransferServiceName),
+            $container->get($config->requestFactoryServiceName),
+            $container->get($config->httpClientServiceName),
+            $container->get($config->securityProviderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName)
+        );
+    }
+}
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/README.md.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/README.md.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..dcb54a4c78f6a4e3a840d7c7bae0c2b87b988cf4
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/README.md.mustache
@@ -0,0 +1,135 @@
+# Client library for {{appName}}
+
+Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+
+## Overview
+This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
+
+- PHP: >=8.0
+- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
+
+
+## How to use
+
+This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}":"{{artifactVersion}}"` to your project `composer.json`) or as a part of your project (just copy generated code from `{{srcBasePath}}` and merge generated `composer.json` into your project `composer.json`).
+
+First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
+
+Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
+
+Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
+
+After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
+
+The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
+
+```PHP
+<?php
+declare(strict_types=1);
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+$dependencies = [
+    'invokables' => [
+        Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
+        Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
+        Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
+    ],
+    'factories' => [
+        {{invokerPackage}}\ApiClient::class => {{invokerPackage}}\ApiClientFactory::class,
+
+        Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
+        Articus\DataTransfer\MetadataProvider\PhpAttribute::class => Articus\DataTransfer\MetadataProvider\Factory\PhpAttribute::class,
+        Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
+        Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
+        Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
+
+        OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
+        OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
+
+        Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
+        {
+            return new Symfony\Component\HttpClient\Psr18Client(
+                new Symfony\Component\HttpClient\NativeHttpClient(),
+                $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+                $container->get(Psr\Http\Message\StreamFactoryInterface::class)
+            );
+        },
+    ],
+    'aliases' => [
+        Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
+        Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
+    ],
+];
+$config = [
+    'dependencies' => $dependencies,
+
+    //Configure DataTransfer library
+    Articus\DataTransfer\Strategy\PluginManager::class => [
+        'invokables' => [
+            'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
+        ],
+          'factories' => [
+            'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
+            'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
+            'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
+            'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
+            'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
+            'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
+        ]
+    ],
+    Articus\DataTransfer\Validator\PluginManager::class => [
+        'invokables' => [
+            'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
+            'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
+        ],
+        'abstract_factories' => [
+            Articus\DataTransfer\Validator\Factory\Laminas::class,
+        ],
+    ],
+    'validators' => [
+        'invokables' => [
+            'Count' => Laminas\Validator\IsCountable::class,
+        ],
+    ],
+
+    //Set API server URL here
+    {{invokerPackage}}\ApiClient::class => [
+        //'server_url' => 'https://api.url',
+    ],
+
+    //Register body coders for used content types here
+    OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
+        'factories' => [
+            //'another/mime-type' => AnotherMimeTypeBodyCoder::class
+        ],
+    ],
+
+    //Register security providers for used security schemes here
+    OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
+        'factories' => [
+            //'another-security-scheme' => AnotherSecuritySchemeProvider::class,
+        ],
+        'aliases' => [
+            //'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
+        ],
+    ],
+];
+$container = new Laminas\ServiceManager\ServiceManager($dependencies);
+$container->setService('config', $config);
+$container->setAlias('Config', 'config');
+
+/** @var {{invokerPackage}}\ApiClient $client */
+$client = $container->get({{invokerPackage}}\ApiClient::class);
+//... and now you can use client methods to call API operations :)
+
+//And one more sample: how to set token for HTTP Bearer authentication
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
+$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
+$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
+$httpBearer->setToken('some-token');
+
+```
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_call.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_call.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..f58c51177317f04c54e038e2169e04c5994586e0
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_call.mustache
@@ -0,0 +1,13 @@
+{{#vendorExtensions}}{{#internal.hasParameterData
+}}$parameters{{#bodyParam}}, {{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam
+}}{{/internal.hasParameterData}}{{/vendorExtensions
+}}{{#bodyParam
+}}$requestContent{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods
+}}{{/bodyParam
+}}{{#hasAuthMethods
+}}$security{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes
+}}{{/hasAuthMethods
+}}{{#hasConsumes
+}}$requestMediaType{{#hasProduces}}, {{/hasProduces
+}}{{/hasConsumes
+}}{{#hasProduces}}$responseMediaType{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_declaration.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_declaration.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..081ec85fe1138f9edd7e2f0e4ee5da8a209fbb86
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_declaration.mustache
@@ -0,0 +1,17 @@
+{{#vendorExtensions}}
+{{#internal.hasParameterData}}
+        {{internal.parameterDataType}} $parameters{{#bodyParam}},{{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam}}
+{{/internal.hasParameterData}}
+{{/vendorExtensions}}
+{{#bodyParam}}
+        {{dataType}} $requestContent{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}
+{{/bodyParam}}
+{{#hasAuthMethods}}
+        iterable $security = ['{{authMethods.0.name}}' => [{{#authMethods.0.scopes}}'{{scope}}', {{/authMethods.0.scopes}}]]{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}
+{{/hasAuthMethods}}
+{{#hasConsumes}}
+        string $requestMediaType = '{{consumes.0.mediaType}}'{{#hasProduces}},{{/hasProduces}}
+{{/hasConsumes}}
+{{#hasProduces}}
+        string $responseMediaType = '{{produces.0.mediaType}}'
+{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_doc.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_doc.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..cf45f4bb7ffe4c1ab7c88876a62b26095e1453d5
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/api_arg_doc.mustache
@@ -0,0 +1,23 @@
+{{#summary}}
+     * {{&summary}}
+{{/summary}}
+{{#description}}
+     * {{&description}}
+{{/description}}
+{{#vendorExtensions}}
+{{#internal.hasParameterData}}
+     * @param {{internal.parameterDataType}} $parameters
+{{/internal.hasParameterData}}
+{{/vendorExtensions}}
+{{#bodyParam}}
+     * @param {{dataType}} $requestContent
+{{/bodyParam}}
+{{#hasAuthMethods}}
+     * @param iterable|string[][] $security
+{{/hasAuthMethods}}
+{{#hasConsumes}}
+     * @param string $requestMediaType
+{{/hasConsumes}}
+{{#hasProduces}}
+     * @param string $responseMediaType
+{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/composer.json.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/composer.json.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..2ca459e65244afb011cf8c535f0ca5177052cc07
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/composer.json.mustache
@@ -0,0 +1,26 @@
+{
+    "name": "{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}",
+    "description": "{{description}}",
+    "license": "unlicense",
+    "version": "{{artifactVersion}}",
+    "type": "library",
+    "require": {
+        "php": "^8.0",
+        "articus/data-transfer": "^0.5",
+        "articus/openapi-generator-common": "^0.2",
+        "articus/openapi-generator-apiclient": "^0.1",
+        "psr/simple-cache": "^1.0",
+        "laminas/laminas-stdlib": "^3.2",
+        "laminas/laminas-validator": "^2.13"
+    },
+    "autoload": {
+        "psr-4": {
+            "": "{{srcBasePath}}/"
+        }
+    },
+    "require-dev": {
+        "laminas/laminas-servicemanager": "^3.6",
+        "laminas/laminas-diactoros": "^2.6",
+        "symfony/http-client": "^5.3"
+    }
+}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/gitignore b/modules/openapi-generator/src/main/resources/php-dt-modern/gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f674bbd2d1fb689c152c42c93829b1e598be21aa
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/gitignore
@@ -0,0 +1,6 @@
+#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
+.idea
+
+# Composer files
+composer.phar
+vendor/
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/list_item_type.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/list_item_type.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..254676614331dc65dffbbe0b2139160640a9be4a
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/list_item_type.mustache
@@ -0,0 +1,8 @@
+{{#items
+}}{{^isContainer
+}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
+}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
+}}{{/isContainer
+}}{{#isContainer
+}}{{dataType}}::class{{/isContainer
+}}{{/items}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/map_item_type.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/map_item_type.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a58e19beca542f7e347ab154867be54c063e1594
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/map_item_type.mustache
@@ -0,0 +1,8 @@
+{{#additionalProperties
+}}{{^isContainer
+}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
+}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
+}}{{/isContainer
+}}{{#isContainer
+}}{{dataType}}::class{{/isContainer
+}}{{/additionalProperties}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/model.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/model.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..98a5149c89b39724976bc6c81b29089ae8b928c7
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/model.mustache
@@ -0,0 +1,13 @@
+<?php
+declare(strict_types=1);
+{{#models}}{{#model}}
+namespace {{package}};
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+{{#vendorExtensions
+}}{{#internal.fromContainer}}{{>model_container}}{{/internal.fromContainer
+}}{{^internal.fromContainer}}{{>model_object}}{{/internal.fromContainer
+}}{{/vendorExtensions
+}}{{^vendorExtensions}}{{>model_object}}{{/vendorExtensions
+}}{{/model}}{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/model_container.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/model_container.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..543194c798b5faff236b2dcd4e91a58b4f0d752e
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/model_container.mustache
@@ -0,0 +1,57 @@
+{{#vars
+}}{{#isArray
+}}#[DTA\Strategy("{{#isPrimitiveType}}ScalarList{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectList{{/isPrimitiveType}}", ["type" => {{>list_item_type}}])]
+{{#minItems}}{{^maxItems
+}}#[DTA\Validator("Count", ["min" => {{minItems}}], blocker: true)]
+{{/maxItems}}{{/minItems
+}}{{^minItems}}{{#maxItems
+}}#[DTA\Validator("Count", ["max" => {{maxItems}}], blocker: true)]
+{{/maxItems}}{{/minItems
+}}{{#minItems}}{{#maxItems
+}}#[DTA\Validator("Count", ["min" => {{minItems}}, "max" => {{maxItems}}], blocker: true)]
+{{/maxItems}}{{/minItems
+}}#[DTA\Validator("Collection", ["validators" => [
+{{#isPrimitiveType
+}}    ["name" => "Scalar", "options" => ["type" => {{>list_item_type}}]]
+{{/isPrimitiveType
+}}{{#isDate
+}}    ["name" => "Date"]
+{{/isDate
+}}{{#isDateTime
+}}    ["name" => "Date", "options" => ["format" => \DateTime::RFC3339]]
+{{/isDateTime
+}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
+}}    ["name" => "TypeCompliant", "options" => ["type" => {{>list_item_type}}]]
+{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
+}}]])]
+{{/isArray
+}}{{#isMap
+}}#[DTA\Strategy("{{#isPrimitiveType}}ScalarMap{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectMap{{/isPrimitiveType}}", ["type" => {{>map_item_type}}])]
+{{#minProperties}}{{^maxProperties
+}}#[DTA\Validator("Count", ["min" => {{minProperties}}], blocker: true)]
+{{/maxProperties}}{{/minProperties
+}}{{^minProperties}}{{#maxProperties
+}}#[DTA\Validator("Count", ["max" => {{maxProperties}}], blocker: true)]
+{{/maxProperties}}{{/minProperties
+}}{{#minProperties}}{{#maxProperties
+}}#[DTA\Validator("Count", ["min" => {{minProperties}}, "max" => {{maxProperties}}], blocker: true)]
+{{/maxProperties}}{{/minProperties
+}}#[DTA\Validator("Collection", ["validators" => [
+{{#isPrimitiveType
+}}    ["name" => "Scalar", "options" => ["type" => {{>map_item_type}}]]
+{{/isPrimitiveType
+}}{{#isDate
+}}    ["name" => "Date"]
+{{/isDate
+}}{{#isDateTime
+}}    ["name" => "Date", "options" => ["format" => \DateTime::RFC3339]]
+{{/isDateTime
+}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
+}}    ["name" => "TypeCompliant", "options" => ["type" => {{>map_item_type}}]]
+{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
+}}]])]
+{{/isMap
+}}{{/vars
+}}class {{classname}} extends \ArrayObject
+{
+}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/model_normal_var.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/model_normal_var.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..8465d19c5d6287b87d7a18132d18536771fe9687
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/model_normal_var.mustache
@@ -0,0 +1,45 @@
+{{#isContainer
+}}    #[DTA\Strategy("Object", ["type" => {{internal.containerDataType}}::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => {{internal.containerDataType}}::class])]
+{{/isContainer
+}}{{^isContainer
+}}{{#isPrimitiveType
+}}    #[DTA\Validator("Scalar", ["type" => "{{dataType}}"])]
+{{/isPrimitiveType
+}}{{#isDate
+}}    #[DTA\Strategy("Date")]
+    #[DTA\Validator("Date")]
+{{/isDate
+}}{{#isDateTime
+}}    #[DTA\Strategy("DateTime")]
+    #[DTA\Validator("Date", ["format" => \DateTime::RFC3339])]
+{{/isDateTime
+}}{{^isPrimitiveType
+}}{{^isDate
+}}{{^isDateTime
+}}    #[DTA\Strategy("Object", ["type" => {{dataType}}::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => {{dataType}}::class])]
+{{/isDateTime
+}}{{/isDate
+}}{{/isPrimitiveType
+}}{{/isContainer
+}}{{#hasValidation
+}}{{#minLength}}{{#maxLength
+}}    #[DTA\Validator("StringLength", ["min" => {{minLength}}, "max" => {{maxLength}}])]
+{{/maxLength}}{{/minLength
+}}{{^minLength}}{{#maxLength
+}}    #[DTA\Validator("StringLength", ["max" => {{maxLength}}])]
+{{/maxLength}}{{/minLength
+}}{{#minLength}}{{^maxLength
+}}    #[DTA\Validator("StringLength", ["min" => {{minLength}}])]
+{{/maxLength}}{{/minLength
+}}{{#minimum
+}}    #[DTA\Validator("GreaterThan", ["min" => {{minimum}}{{^exclusiveMinimum}}, "inclusive" => true{{/exclusiveMinimum}}])]
+{{/minimum
+}}{{#maximum
+}}    #[DTA\Validator("LessThan", ["max" => {{maximum}}{{^exclusiveMaximum}}, "inclusive" => true{{/exclusiveMaximum}}])]
+{{/maximum
+}}{{#pattern
+}}    #[DTA\Validator("Regex", ["pattern" => "{{{pattern}}}"])]
+{{/pattern
+}}{{/hasValidation}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/model_object.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/model_object.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..1775708b578691da3dd9ffe19762905baf44d993
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/model_object.mustache
@@ -0,0 +1,23 @@
+{{#description
+}}/**
+ * {{description}}
+ */
+{{/description
+}}class {{classname}}
+{
+{{#vars
+}}{{#description
+}}    /**
+     * {{description}}
+     */
+{{/description
+}}    #[DTA\Data({{#vendorExtensions}}{{#internal.fromParameters}}subset: "{{internal.parameterLocation}}", {{/internal.fromParameters}}{{/vendorExtensions}}field: "{{baseName}}"{{^required}}, nullable: true{{/required}})]
+{{#vendorExtensions
+}}{{#internal.fromParameters}}{{>model_query_var}}{{/internal.fromParameters
+}}{{^internal.fromParameters}}{{>model_normal_var}}{{/internal.fromParameters
+}}{{/vendorExtensions
+}}{{^vendorExtensions}}{{>model_normal_var}}{{/vendorExtensions
+}}    public {{dataType}}|null ${{name}} = null;
+
+{{/vars
+}}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt-modern/model_query_var.mustache b/modules/openapi-generator/src/main/resources/php-dt-modern/model_query_var.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a81d14f0ed150d6a2acb639f1b74391dd2e8299f
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt-modern/model_query_var.mustache
@@ -0,0 +1,51 @@
+{{#isArray
+}}{{#isPrimitiveType
+}}    #[DTA\Strategy("QueryStringScalarArray", ["type" => {{>list_item_type}}, "format" => "{{internal.collectionFormat}}"], "{{internal.parameterLocation}}")]
+    #[DTA\Validator("QueryStringScalarArray", ["type" => {{>list_item_type}}, "format" => "{{internal.collectionFormat}}"{{#minItems}}, "min_items" => {{minItems}}{{/minItems}}{{#maxItems}}, "max_items" => {{maxItems}}{{/maxItems}}], subset: "{{internal.parameterLocation}}")]
+{{/isPrimitiveType
+}}{{^isPrimitiveType
+}}    // TODO add validator(s) and strategy for list of {{>list_item_type}} and collection format {{internal.collectionFormat}} inside query string
+{{/isPrimitiveType
+}}{{/isArray
+}}{{#isMap
+}}    // TODO add validator(s) and strategy for map of {{>map_item_type}} and collection format {{internal.collectionFormat}} inside query string
+{{/isMap
+}}{{^isContainer
+}}{{#isPrimitiveType
+}}    #[DTA\Strategy("QueryStringScalar", ["type" => "{{dataType}}"], "{{internal.parameterLocation}}")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "{{dataType}}"], subset: "{{internal.parameterLocation}}")]
+{{/isPrimitiveType
+}}{{#isDate
+}}    #[DTA\Strategy("Date", subset: "{{internal.parameterLocation}}")]
+    #[DTA\Validator("Date", subset: "{{internal.parameterLocation}}")]
+{{/isDate
+}}{{#isDateTime
+}}    #[DTA\Strategy("DateTime", subset: "{{internal.parameterLocation}}")]
+    #[DTA\Validator("Date", ["format" => \DateTime::RFC3339], subset: "{{internal.parameterLocation}}")]
+{{/isDateTime
+}}{{^isPrimitiveType
+}}{{^isDate}}{{^isDateTime
+}}    // TODO add validator(s) and strategy for {{dataType}} inside query string
+{{/isDateTime}}{{/isDate
+}}{{/isPrimitiveType
+}}{{/isContainer
+}}{{#hasValidation
+}}{{#minLength}}{{#maxLength
+}}    #[DTA\Validator("StringLength", ["min" => {{minLength}}, "max" => {{maxLength}}], subset: "{{internal.parameterLocation}}")]
+{{/maxLength}}{{/minLength
+}}{{^minLength}}{{#maxLength
+}}    #[DTA\Validator("StringLength", ["max" => {{maxLength}}], subset: "{{internal.parameterLocation}}")]
+{{/maxLength}}{{/minLength
+}}{{#minLength}}{{^maxLength
+}}    #[DTA\Validator("StringLength", ["min" => {{minLength}}], subset: "{{internal.parameterLocation}}")]
+{{/maxLength}}{{/minLength
+}}{{#minimum
+}}    #[DTA\Validator("GreaterThan", ["min" => {{minimum}}{{^exclusiveMinimum}}, "inclusive" => true{{/exclusiveMinimum}}], subset: "{{internal.parameterLocation}}")]
+{{/minimum
+}}{{#maximum
+}}    #[DTA\Validator("LessThan", ["max" => {{maximum}}{{^exclusiveMaximum}}, "inclusive" => true{{/exclusiveMaximum}}], subset: "{{internal.parameterLocation}}")]
+{{/maximum
+}}{{#pattern
+}}    #[DTA\Validator("Regex", ["pattern" => "{{{pattern}}}"], subset: "{{internal.parameterLocation}}")]
+{{/pattern
+}}{{/hasValidation}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/ApiClient.php.mustache b/modules/openapi-generator/src/main/resources/php-dt/ApiClient.php.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..b86f285a0a7fcb25f0841c0cb36a0d401703dd8b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/ApiClient.php.mustache
@@ -0,0 +1,123 @@
+<?php
+declare(strict_types=1);
+
+namespace {{invokerPackage}};
+{{#apiInfo}}
+{{#apis}}
+{{#operations}}
+
+use Articus\DataTransfer as DT;
+use OpenAPIGenerator\APIClient as OAGAC;
+use Psr\Http\Client\ClientExceptionInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+{{#appName}}
+ * {{&appName}}
+{{/appName}}
+{{#appDescription}}
+ * {{&appDescription}}
+{{/appDescription}}
+{{#version}}
+ * The version of the OpenAPI document: {{version}}
+{{/version}}
+ */
+class ApiClient extends OAGAC\AbstractApiClient
+{
+{{#operation}}
+    //region {{operationId}}
+    /**
+{{>api_arg_doc
+}}     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function {{operationId}}Raw(
+{{>api_arg_declaration
+}}    ): ResponseInterface
+    {
+        $request = $this->createRequest('{{httpMethod}}', '{{path}}', {{#pathParams.0}}$this->getPathParameters($parameters){{/pathParams.0}}{{^pathParams.0}}[]{{/pathParams.0}}, {{#queryParams.0}}$this->getQueryParameters($parameters){{/queryParams.0}}{{^queryParams.0}}[]{{/queryParams.0}});
+{{#headerParams.0}}
+        $request = $this->addCustomHeaders($request, $parameters);
+{{/headerParams.0}}
+{{#cookieParams.0}}
+        $request = $this->addCookies($request, $parameters);
+{{/cookieParams.0}}
+{{#bodyParam}}
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+{{/bodyParam}}
+{{#hasProduces}}
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+{{/hasProduces}}
+{{#hasAuthMethods}}
+        $request = $this->addSecurity($request, $security);
+{{/hasAuthMethods}}
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+{{>api_arg_doc
+}}     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function {{operationId}}(
+{{>api_arg_declaration
+}}    ): array
+    {
+        $response = $this->{{operationId}}Raw({{>api_arg_call}});
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+{{#responses}}
+            {{#isDefault}}default{{/isDefault}}{{^isDefault}}case {{code}}{{/isDefault}}:
+{{#message}}
+                /* {{&message}} */
+{{/message}}
+{{#isModel}}
+                $responseContent = new {{dataType}}();
+{{/isModel}}
+{{^isModel}}
+{{#isArray}}
+                $responseContent = new {{dataType}}();
+{{/isArray}}
+{{/isModel}}
+{{^isModel}}
+{{^isArray}}
+{{#isMap}}
+                $responseContent = new {{dataType}}();
+{{/isMap}}
+{{/isArray}}
+{{/isModel}}
+                break;
+{{/responses}}
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+{{>api_arg_doc
+}}     * @return {{#returnType}}{{returnType}}{{/returnType}}{{^returnType}}mixed{{/returnType}}
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function {{operationId}}Result(
+{{>api_arg_declaration
+}}    ){{#returnType}}: {{returnType}}{{/returnType}}
+    {
+        return $this->getSuccessfulContent(...$this->{{operationId}}({{>api_arg_call}}));
+    }
+    //endregion
+{{^-last}}
+
+{{/-last}}
+{{/operation}}
+}
+
+{{/operations}}
+{{/apis}}
+{{/apiInfo}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/ApiClientFactory.php.mustache b/modules/openapi-generator/src/main/resources/php-dt/ApiClientFactory.php.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a36880d3d84e32525847eed8cba7e58252a23026
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/ApiClientFactory.php.mustache
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace {{invokerPackage}};
+
+use Articus\DataTransfer as DT;
+use Interop\Container\ContainerInterface;
+use OpenAPIGenerator\APIClient as OAGAC;
+
+class ApiClientFactory extends DT\ConfigAwareFactory
+{
+    public function __construct(string $configKey = ApiClient::class)
+    {
+        parent::__construct($configKey);
+    }
+
+    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
+    {
+        $config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
+        return new ApiClient(
+            $config->serverUrl,
+            $container->get($config->dataTransferServiceName),
+            $container->get($config->requestFactoryServiceName),
+            $container->get($config->httpClientServiceName),
+            $container->get($config->securityProviderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName)
+        );
+    }
+}
diff --git a/modules/openapi-generator/src/main/resources/php-dt/README.md.mustache b/modules/openapi-generator/src/main/resources/php-dt/README.md.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..0185e9584ce9b1d8c13a41d5bff568489e9930e2
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/README.md.mustache
@@ -0,0 +1,135 @@
+# Client library for {{appName}}
+
+Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+
+## Overview
+This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
+
+- PHP: >=7.3
+- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
+
+
+## How to use
+
+This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}":"{{artifactVersion}}"` to your project `composer.json`) or as a part of your project (just copy generated code from `{{srcBasePath}}` and merge generated `composer.json` into your project `composer.json`).
+
+First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
+
+Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
+
+Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
+
+After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
+
+The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
+
+```PHP
+<?php
+declare(strict_types=1);
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+$dependencies = [
+    'invokables' => [
+        Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
+        Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
+        Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
+    ],
+    'factories' => [
+        {{invokerPackage}}\ApiClient::class => {{invokerPackage}}\ApiClientFactory::class,
+
+        Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
+        Articus\DataTransfer\MetadataProvider\Annotation::class => Articus\DataTransfer\MetadataProvider\Factory\Annotation::class,
+        Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
+        Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
+        Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
+
+        OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
+        OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
+
+        Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
+        {
+            return new Symfony\Component\HttpClient\Psr18Client(
+                new Symfony\Component\HttpClient\NativeHttpClient(),
+                $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+                $container->get(Psr\Http\Message\StreamFactoryInterface::class)
+            );
+        },
+    ],
+    'aliases' => [
+        Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
+        Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
+    ],
+];
+$config = [
+    'dependencies' => $dependencies,
+
+    //Configure DataTransfer library
+    Articus\DataTransfer\Strategy\PluginManager::class => [
+        'invokables' => [
+            'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
+        ],
+          'factories' => [
+            'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
+            'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
+            'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
+            'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
+            'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
+            'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
+        ]
+    ],
+    Articus\DataTransfer\Validator\PluginManager::class => [
+        'invokables' => [
+            'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
+            'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
+        ],
+        'abstract_factories' => [
+            Articus\DataTransfer\Validator\Factory\Laminas::class,
+        ],
+    ],
+    'validators' => [
+        'invokables' => [
+            'Count' => Laminas\Validator\IsCountable::class,
+        ],
+    ],
+
+    //Set API server URL here
+    {{invokerPackage}}\ApiClient::class => [
+        //'server_url' => 'https://api.url',
+    ],
+
+    //Register body coders for used content types here
+    OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
+        'factories' => [
+            //'another/mime-type' => AnotherMimeTypeBodyCoder::class
+        ],
+    ],
+
+    //Register security providers for used security schemes here
+    OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
+        'factories' => [
+            //'another-security-scheme' => AnotherSecuritySchemeProvider::class,
+        ],
+        'aliases' => [
+            //'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
+        ],
+    ],
+];
+$container = new Laminas\ServiceManager\ServiceManager($dependencies);
+$container->setService('config', $config);
+$container->setAlias('Config', 'config');
+
+/** @var {{invokerPackage}}\ApiClient $client */
+$client = $container->get({{invokerPackage}}\ApiClient::class);
+//... and now you can use client methods to call API operations :)
+
+//And one more sample: how to set token for HTTP Bearer authentication
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
+$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
+$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
+$httpBearer->setToken('some-token');
+
+```
diff --git a/modules/openapi-generator/src/main/resources/php-dt/api_arg_call.mustache b/modules/openapi-generator/src/main/resources/php-dt/api_arg_call.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..f58c51177317f04c54e038e2169e04c5994586e0
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/api_arg_call.mustache
@@ -0,0 +1,13 @@
+{{#vendorExtensions}}{{#internal.hasParameterData
+}}$parameters{{#bodyParam}}, {{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam
+}}{{/internal.hasParameterData}}{{/vendorExtensions
+}}{{#bodyParam
+}}$requestContent{{#hasAuthMethods}}, {{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods
+}}{{/bodyParam
+}}{{#hasAuthMethods
+}}$security{{#hasConsumes}}, {{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}}, {{/hasProduces}}{{/hasConsumes
+}}{{/hasAuthMethods
+}}{{#hasConsumes
+}}$requestMediaType{{#hasProduces}}, {{/hasProduces
+}}{{/hasConsumes
+}}{{#hasProduces}}$responseMediaType{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/api_arg_declaration.mustache b/modules/openapi-generator/src/main/resources/php-dt/api_arg_declaration.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..081ec85fe1138f9edd7e2f0e4ee5da8a209fbb86
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/api_arg_declaration.mustache
@@ -0,0 +1,17 @@
+{{#vendorExtensions}}
+{{#internal.hasParameterData}}
+        {{internal.parameterDataType}} $parameters{{#bodyParam}},{{/bodyParam}}{{^bodyParam}}{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}{{/bodyParam}}
+{{/internal.hasParameterData}}
+{{/vendorExtensions}}
+{{#bodyParam}}
+        {{dataType}} $requestContent{{#hasAuthMethods}},{{/hasAuthMethods}}{{^hasAuthMethods}}{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}{{/hasAuthMethods}}
+{{/bodyParam}}
+{{#hasAuthMethods}}
+        iterable $security = ['{{authMethods.0.name}}' => [{{#authMethods.0.scopes}}'{{scope}}', {{/authMethods.0.scopes}}]]{{#hasConsumes}},{{/hasConsumes}}{{^hasConsumes}}{{#hasProduces}},{{/hasProduces}}{{/hasConsumes}}
+{{/hasAuthMethods}}
+{{#hasConsumes}}
+        string $requestMediaType = '{{consumes.0.mediaType}}'{{#hasProduces}},{{/hasProduces}}
+{{/hasConsumes}}
+{{#hasProduces}}
+        string $responseMediaType = '{{produces.0.mediaType}}'
+{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/api_arg_doc.mustache b/modules/openapi-generator/src/main/resources/php-dt/api_arg_doc.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..cf45f4bb7ffe4c1ab7c88876a62b26095e1453d5
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/api_arg_doc.mustache
@@ -0,0 +1,23 @@
+{{#summary}}
+     * {{&summary}}
+{{/summary}}
+{{#description}}
+     * {{&description}}
+{{/description}}
+{{#vendorExtensions}}
+{{#internal.hasParameterData}}
+     * @param {{internal.parameterDataType}} $parameters
+{{/internal.hasParameterData}}
+{{/vendorExtensions}}
+{{#bodyParam}}
+     * @param {{dataType}} $requestContent
+{{/bodyParam}}
+{{#hasAuthMethods}}
+     * @param iterable|string[][] $security
+{{/hasAuthMethods}}
+{{#hasConsumes}}
+     * @param string $requestMediaType
+{{/hasConsumes}}
+{{#hasProduces}}
+     * @param string $responseMediaType
+{{/hasProduces}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/composer.json.mustache b/modules/openapi-generator/src/main/resources/php-dt/composer.json.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a0d5ae7066cc9f2738670327a2d0fdc233c8631e
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/composer.json.mustache
@@ -0,0 +1,27 @@
+{
+    "name": "{{#lambda.lowercase}}{{gitUserId}}/{{gitRepoId}}{{/lambda.lowercase}}",
+    "description": "{{description}}",
+    "license": "unlicense",
+    "version": "{{artifactVersion}}",
+    "type": "library",
+    "require": {
+        "php": "^7.3 || ^8.0",
+        "articus/data-transfer": "^0.5",
+        "articus/openapi-generator-common": "^0.2",
+        "articus/openapi-generator-apiclient": "^0.1",
+        "doctrine/annotations": "^1.10",
+        "psr/simple-cache": "^1.0",
+        "laminas/laminas-stdlib": "^3.2",
+        "laminas/laminas-validator": "^2.13"
+    },
+    "autoload": {
+        "psr-4": {
+            "": "{{srcBasePath}}/"
+        }
+    },
+    "require-dev": {
+        "laminas/laminas-servicemanager": "^3.6",
+        "laminas/laminas-diactoros": "^2.6",
+        "symfony/http-client": "^5.3"
+    }
+}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/gitignore b/modules/openapi-generator/src/main/resources/php-dt/gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f674bbd2d1fb689c152c42c93829b1e598be21aa
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/gitignore
@@ -0,0 +1,6 @@
+#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
+.idea
+
+# Composer files
+composer.phar
+vendor/
diff --git a/modules/openapi-generator/src/main/resources/php-dt/list_item_type.mustache b/modules/openapi-generator/src/main/resources/php-dt/list_item_type.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..254676614331dc65dffbbe0b2139160640a9be4a
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/list_item_type.mustache
@@ -0,0 +1,8 @@
+{{#items
+}}{{^isContainer
+}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
+}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
+}}{{/isContainer
+}}{{#isContainer
+}}{{dataType}}::class{{/isContainer
+}}{{/items}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/map_item_type.mustache b/modules/openapi-generator/src/main/resources/php-dt/map_item_type.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..a58e19beca542f7e347ab154867be54c063e1594
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/map_item_type.mustache
@@ -0,0 +1,8 @@
+{{#additionalProperties
+}}{{^isContainer
+}}{{#isPrimitiveType}}"{{dataType}}"{{/isPrimitiveType
+}}{{^isPrimitiveType}}{{dataType}}::class{{/isPrimitiveType
+}}{{/isContainer
+}}{{#isContainer
+}}{{dataType}}::class{{/isContainer
+}}{{/additionalProperties}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/model.mustache b/modules/openapi-generator/src/main/resources/php-dt/model.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..612c5620938b7a6ce632fc2fd3a2b79de7c51b7d
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/model.mustache
@@ -0,0 +1,13 @@
+<?php
+declare(strict_types=1);
+{{#models}}{{#model}}
+namespace {{package}};
+
+use Articus\DataTransfer\Annotation as DTA;
+
+{{#vendorExtensions
+}}{{#internal.fromContainer}}{{>model_container}}{{/internal.fromContainer
+}}{{^internal.fromContainer}}{{>model_object}}{{/internal.fromContainer
+}}{{/vendorExtensions
+}}{{^vendorExtensions}}{{>model_object}}{{/vendorExtensions
+}}{{/model}}{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/php-dt/model_container.mustache b/modules/openapi-generator/src/main/resources/php-dt/model_container.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..bbecf5ed190049941c5baddebd1dd59b85b45e9b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/model_container.mustache
@@ -0,0 +1,59 @@
+/**
+{{#vars
+}}{{#isArray
+}} * @DTA\Strategy(name="{{#isPrimitiveType}}ScalarList{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectList{{/isPrimitiveType}}", options={"type":{{>list_item_type}}})
+{{#minItems}}{{^maxItems
+}} * @DTA\Validator(name="Count", options={"min":{{minItems}}}, blocker=true)
+{{/maxItems}}{{/minItems
+}}{{^minItems}}{{#maxItems
+}} * @DTA\Validator(name="Count", options={"max":{{maxItems}}}, blocker=true)
+{{/maxItems}}{{/minItems
+}}{{#minItems}}{{#maxItems
+}} * @DTA\Validator(name="Count", options={"min":{{minItems}},"max":{{maxItems}}}, blocker=true)
+{{/maxItems}}{{/minItems
+}} * @DTA\Validator(name="Collection", options={"validators":{
+{{#isPrimitiveType
+}} *     {"name":"Scalar", "options":{"type":{{>list_item_type}}}}
+{{/isPrimitiveType
+}}{{#isDate
+}} *     {"name":"Date"}
+{{/isDate
+}}{{#isDateTime
+}} *     {"name":"Date", "options":{"format": \DateTime::RFC3339}}
+{{/isDateTime
+}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
+}} *     {"name":"TypeCompliant", "options":{"type":{{>list_item_type}}}}
+{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
+}} * }})
+{{/isArray
+}}{{#isMap
+}} * @DTA\Strategy(name="{{#isPrimitiveType}}ScalarMap{{/isPrimitiveType}}{{^isPrimitiveType}}ObjectMap{{/isPrimitiveType}}", options={"type":{{>map_item_type}}})
+{{#minProperties}}{{^maxProperties
+}} * @DTA\Validator(name="Count", options={"min":{{minProperties}}}, blocker=true)
+{{/maxProperties}}{{/minProperties
+}}{{^minProperties}}{{#maxProperties
+}} * @DTA\Validator(name="Count", options={"max":{{maxProperties}}}, blocker=true)
+{{/maxProperties}}{{/minProperties
+}}{{#minProperties}}{{#maxProperties
+}} * @DTA\Validator(name="Count", options={"min":{{minProperties}},"max":{{maxProperties}}}, blocker=true)
+{{/maxProperties}}{{/minProperties
+}} * @DTA\Validator(name="Collection", options={"validators":{
+{{#isPrimitiveType
+}} *     {"name":"Scalar", "options":{"type":{{>map_item_type}}}}
+{{/isPrimitiveType
+}}{{#isDate
+}} *     {"name":"Date"}
+{{/isDate
+}}{{#isDateTime
+}} *     {"name":"Date", "options":{"format": \DateTime::RFC3339}}
+{{/isDateTime
+}}{{^isPrimitiveType}}{{^isDate}}{{^isDateTime
+}} *     {"name":"TypeCompliant", "options":{"type":{{>map_item_type}}}}
+{{/isDateTime}}{{/isDate}}{{/isPrimitiveType
+}} * }})
+{{/isMap
+}}{{/vars
+}} */
+class {{classname}} extends \ArrayObject
+{
+}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/model_normal_var.mustache b/modules/openapi-generator/src/main/resources/php-dt/model_normal_var.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..1354c0eeda6ca59d94f9bb5d73ba6298afe3db5b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/model_normal_var.mustache
@@ -0,0 +1,45 @@
+{{#isContainer
+}}     * @DTA\Strategy(name="Object", options={"type":{{internal.containerDataType}}::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":{{internal.containerDataType}}::class})
+{{/isContainer
+}}{{^isContainer
+}}{{#isPrimitiveType
+}}     * @DTA\Validator(name="Scalar", options={"type":"{{dataType}}"})
+{{/isPrimitiveType
+}}{{#isDate
+}}     * @DTA\Strategy(name="Date")
+     * @DTA\Validator(name="Date")
+{{/isDate
+}}{{#isDateTime
+}}     * @DTA\Strategy(name="DateTime")
+     * @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
+{{/isDateTime
+}}{{^isPrimitiveType
+}}{{^isDate
+}}{{^isDateTime
+}}     * @DTA\Strategy(name="Object", options={"type":{{dataType}}::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":{{dataType}}::class})
+{{/isDateTime
+}}{{/isDate
+}}{{/isPrimitiveType
+}}{{/isContainer
+}}{{#hasValidation
+}}{{#minLength}}{{#maxLength
+}}     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
+{{/maxLength}}{{/minLength
+}}{{^minLength}}{{#maxLength
+}}     * @DTA\Validator(name="StringLength", options={"max":{{maxLength}}})
+{{/maxLength}}{{/minLength
+}}{{#minLength}}{{^maxLength
+}}     * @DTA\Validator(name="StringLength", options={"min":{{minLength}}})
+{{/maxLength}}{{/minLength
+}}{{#minimum
+}}     * @DTA\Validator(name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
+{{/minimum
+}}{{#maximum
+}}     * @DTA\Validator(name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
+{{/maximum
+}}{{#pattern
+}}     * @DTA\Validator(name="Regex", options={"pattern":"{{{pattern}}}"})
+{{/pattern
+}}{{/hasValidation}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/model_object.mustache b/modules/openapi-generator/src/main/resources/php-dt/model_object.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..e47e48981aa74d624ef687debbe4f8c4b107e439
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/model_object.mustache
@@ -0,0 +1,24 @@
+/**
+{{#description
+}} * {{description}}
+{{/description
+}} */
+class {{classname}}
+{
+{{#vars
+}}    /**
+{{#description
+}}     * {{description}}
+{{/description
+}}     * @DTA\Data({{#vendorExtensions}}{{#internal.fromParameters}}subset="{{internal.parameterLocation}}", {{/internal.fromParameters}}{{/vendorExtensions}}field="{{baseName}}"{{^required}}, nullable=true{{/required}})
+{{#vendorExtensions
+}}{{#internal.fromParameters}}{{>model_query_var}}{{/internal.fromParameters
+}}{{^internal.fromParameters}}{{>model_normal_var}}{{/internal.fromParameters
+}}{{/vendorExtensions
+}}{{^vendorExtensions}}{{>model_normal_var}}{{/vendorExtensions
+}}     * @var {{dataType}}|null
+     */
+    public ${{name}};
+
+{{/vars
+}}}
\ No newline at end of file
diff --git a/modules/openapi-generator/src/main/resources/php-dt/model_query_var.mustache b/modules/openapi-generator/src/main/resources/php-dt/model_query_var.mustache
new file mode 100644
index 0000000000000000000000000000000000000000..44a7a618edac1bc59e3f9b2c432c4aac77a675a2
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/php-dt/model_query_var.mustache
@@ -0,0 +1,51 @@
+{{#isArray
+}}{{#isPrimitiveType
+}}     * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="QueryStringScalarArray", options={"type":{{>list_item_type}}, "format":"{{internal.collectionFormat}}"})
+     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="QueryStringScalarArray", options={"type":{{>list_item_type}}, "format":"{{internal.collectionFormat}}"{{#minItems}}, "min_items":{{minItems}}{{/minItems}}{{#maxItems}}, "max_items":{{maxItems}}{{/maxItems}}})
+{{/isPrimitiveType
+}}{{^isPrimitiveType
+}}     * TODO add validator(s) and strategy for list of {{>list_item_type}} and collection format {{internal.collectionFormat}} inside query string
+{{/isPrimitiveType
+}}{{/isArray
+}}{{#isMap
+}}     * TODO add validator(s) and strategy for map of {{>map_item_type}} and collection format {{internal.collectionFormat}} inside query string
+{{/isMap
+}}{{^isContainer
+}}{{#isPrimitiveType
+}}     * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="QueryStringScalar", options={"type":"{{dataType}}"})
+     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="QueryStringScalar", options={"type":"{{dataType}}"})
+{{/isPrimitiveType
+}}{{#isDate
+}}     * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="Date")
+     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="Date")
+{{/isDate
+}}{{#isDateTime
+}}     * @DTA\Strategy(subset="{{internal.parameterLocation}}", name="DateTime")
+     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="Date", options={"format": \DateTime::RFC3339})
+{{/isDateTime
+}}{{^isPrimitiveType
+}}{{^isDate}}{{^isDateTime
+}}     * TODO add validator(s) and strategy for {{dataType}} inside query string
+{{/isDateTime}}{{/isDate
+}}{{/isPrimitiveType
+}}{{/isContainer
+}}{{#hasValidation
+}}{{#minLength}}{{#maxLength
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"min":{{minLength}}, "max":{{maxLength}}})
+{{/maxLength}}{{/minLength
+}}{{^minLength}}{{#maxLength
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"max":{{maxLength}}})
+{{/maxLength}}{{/minLength
+}}{{#minLength}}{{^maxLength
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="StringLength", options={"min":{{minLength}}})
+{{/maxLength}}{{/minLength
+}}{{#minimum
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="GreaterThan", options={"min":{{minimum}}{{^exclusiveMinimum}}, "inclusive":true{{/exclusiveMinimum}}})
+{{/minimum
+}}{{#maximum
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="LessThan", options={"max":{{maximum}}{{^exclusiveMaximum}}, "inclusive":true{{/exclusiveMaximum}}})
+{{/maximum
+}}{{#pattern
+}}     * @DTA\Validator(subset="{{internal.parameterLocation}}", name="Regex", options={"pattern":"{{{pattern}}}"})
+{{/pattern
+}}{{/hasValidation}}
\ No newline at end of file
diff --git a/samples/client/petstore/php-dt-modern/.gitignore b/samples/client/petstore/php-dt-modern/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f674bbd2d1fb689c152c42c93829b1e598be21aa
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/.gitignore
@@ -0,0 +1,6 @@
+#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
+.idea
+
+# Composer files
+composer.phar
+vendor/
diff --git a/samples/client/petstore/php-dt-modern/.openapi-generator-ignore b/samples/client/petstore/php-dt-modern/.openapi-generator-ignore
new file mode 100644
index 0000000000000000000000000000000000000000..7484ee590a3894506cf063799b885428f95a71be
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/php-dt-modern/.openapi-generator/FILES b/samples/client/petstore/php-dt-modern/.openapi-generator/FILES
new file mode 100644
index 0000000000000000000000000000000000000000..b1c5f88c6f89a9cf693cc6b477da2a39d440fc4f
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/.openapi-generator/FILES
@@ -0,0 +1,62 @@
+.gitignore
+README.md
+composer.json
+src/App/ApiClient.php
+src/App/ApiClientFactory.php
+src/App/DTO/ApiResponse.php
+src/App/DTO/Category.php
+src/App/DTO/Collection.php
+src/App/DTO/Collection1.php
+src/App/DTO/Collection10.php
+src/App/DTO/Collection11.php
+src/App/DTO/Collection12.php
+src/App/DTO/Collection13.php
+src/App/DTO/Collection14.php
+src/App/DTO/Collection15.php
+src/App/DTO/Collection16.php
+src/App/DTO/Collection17.php
+src/App/DTO/Collection18.php
+src/App/DTO/Collection19.php
+src/App/DTO/Collection2.php
+src/App/DTO/Collection20.php
+src/App/DTO/Collection21.php
+src/App/DTO/Collection22.php
+src/App/DTO/Collection23.php
+src/App/DTO/Collection24.php
+src/App/DTO/Collection25.php
+src/App/DTO/Collection26.php
+src/App/DTO/Collection27.php
+src/App/DTO/Collection28.php
+src/App/DTO/Collection29.php
+src/App/DTO/Collection3.php
+src/App/DTO/Collection30.php
+src/App/DTO/Collection31.php
+src/App/DTO/Collection32.php
+src/App/DTO/Collection33.php
+src/App/DTO/Collection34.php
+src/App/DTO/Collection35.php
+src/App/DTO/Collection36.php
+src/App/DTO/Collection4.php
+src/App/DTO/Collection5.php
+src/App/DTO/Collection6.php
+src/App/DTO/Collection7.php
+src/App/DTO/Collection8.php
+src/App/DTO/Collection9.php
+src/App/DTO/DeleteOrderParameterData.php
+src/App/DTO/DeletePetParameterData.php
+src/App/DTO/DeleteUserParameterData.php
+src/App/DTO/FindPetsByStatusParameterData.php
+src/App/DTO/FindPetsByTagsParameterData.php
+src/App/DTO/GetOrderByIdParameterData.php
+src/App/DTO/GetPetByIdParameterData.php
+src/App/DTO/GetUserByNameParameterData.php
+src/App/DTO/InlineObject.php
+src/App/DTO/InlineObject1.php
+src/App/DTO/LoginUserParameterData.php
+src/App/DTO/Order.php
+src/App/DTO/Pet.php
+src/App/DTO/Tag.php
+src/App/DTO/UpdatePetWithFormParameterData.php
+src/App/DTO/UpdateUserParameterData.php
+src/App/DTO/UploadFileParameterData.php
+src/App/DTO/User.php
diff --git a/samples/client/petstore/php-dt-modern/.openapi-generator/VERSION b/samples/client/petstore/php-dt-modern/.openapi-generator/VERSION
new file mode 100644
index 0000000000000000000000000000000000000000..862529f8cacd978b63ae68f3674151d549b33168
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/.openapi-generator/VERSION
@@ -0,0 +1 @@
+5.2.1-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/php-dt-modern/README.md b/samples/client/petstore/php-dt-modern/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..fbe290e8adc372310d0c72cbecc26e68bc40ae38
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/README.md
@@ -0,0 +1,135 @@
+# Client library for OpenAPI Petstore
+
+Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+
+## Overview
+This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
+
+- PHP: >=8.0
+- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
+
+
+## How to use
+
+This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"git_user_id/git_repo_id":"1.0.0"` to your project `composer.json`) or as a part of your project (just copy generated code from `src` and merge generated `composer.json` into your project `composer.json`).
+
+First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
+
+Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
+
+Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
+
+After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
+
+The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
+
+```PHP
+<?php
+declare(strict_types=1);
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+$dependencies = [
+    'invokables' => [
+        Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
+        Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
+        Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
+    ],
+    'factories' => [
+        App\ApiClient::class => App\ApiClientFactory::class,
+
+        Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
+        Articus\DataTransfer\MetadataProvider\PhpAttribute::class => Articus\DataTransfer\MetadataProvider\Factory\PhpAttribute::class,
+        Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
+        Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
+        Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
+
+        OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
+        OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
+
+        Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
+        {
+            return new Symfony\Component\HttpClient\Psr18Client(
+                new Symfony\Component\HttpClient\NativeHttpClient(),
+                $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+                $container->get(Psr\Http\Message\StreamFactoryInterface::class)
+            );
+        },
+    ],
+    'aliases' => [
+        Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
+        Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\PhpAttribute::class,
+    ],
+];
+$config = [
+    'dependencies' => $dependencies,
+
+    //Configure DataTransfer library
+    Articus\DataTransfer\Strategy\PluginManager::class => [
+        'invokables' => [
+            'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
+        ],
+          'factories' => [
+            'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
+            'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
+            'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
+            'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
+            'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
+            'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
+        ]
+    ],
+    Articus\DataTransfer\Validator\PluginManager::class => [
+        'invokables' => [
+            'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
+            'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
+        ],
+        'abstract_factories' => [
+            Articus\DataTransfer\Validator\Factory\Laminas::class,
+        ],
+    ],
+    'validators' => [
+        'invokables' => [
+            'Count' => Laminas\Validator\IsCountable::class,
+        ],
+    ],
+
+    //Set API server URL here
+    App\ApiClient::class => [
+        //'server_url' => 'https://api.url',
+    ],
+
+    //Register body coders for used content types here
+    OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
+        'factories' => [
+            //'another/mime-type' => AnotherMimeTypeBodyCoder::class
+        ],
+    ],
+
+    //Register security providers for used security schemes here
+    OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
+        'factories' => [
+            //'another-security-scheme' => AnotherSecuritySchemeProvider::class,
+        ],
+        'aliases' => [
+            //'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
+        ],
+    ],
+];
+$container = new Laminas\ServiceManager\ServiceManager($dependencies);
+$container->setService('config', $config);
+$container->setAlias('Config', 'config');
+
+/** @var App\ApiClient $client */
+$client = $container->get(App\ApiClient::class);
+//... and now you can use client methods to call API operations :)
+
+//And one more sample: how to set token for HTTP Bearer authentication
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
+$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
+$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
+$httpBearer->setToken('some-token');
+
+```
diff --git a/samples/client/petstore/php-dt-modern/composer.json b/samples/client/petstore/php-dt-modern/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..b039e9df0c1cf6d8526e528144ea7fba45565654
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/composer.json
@@ -0,0 +1,26 @@
+{
+    "name": "git_user_id/git_repo_id",
+    "description": "",
+    "license": "unlicense",
+    "version": "1.0.0",
+    "type": "library",
+    "require": {
+        "php": "^8.0",
+        "articus/data-transfer": "^0.5",
+        "articus/openapi-generator-common": "^0.2",
+        "articus/openapi-generator-apiclient": "^0.1",
+        "psr/simple-cache": "^1.0",
+        "laminas/laminas-stdlib": "^3.2",
+        "laminas/laminas-validator": "^2.13"
+    },
+    "autoload": {
+        "psr-4": {
+            "": "src/"
+        }
+    },
+    "require-dev": {
+        "laminas/laminas-servicemanager": "^3.6",
+        "laminas/laminas-diactoros": "^2.6",
+        "symfony/http-client": "^5.3"
+    }
+}
\ No newline at end of file
diff --git a/samples/client/petstore/php-dt-modern/src/App/ApiClient.php b/samples/client/petstore/php-dt-modern/src/App/ApiClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4e56f6f9da785af87a3b92bf1aee51748ae725f
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/ApiClient.php
@@ -0,0 +1,1471 @@
+<?php
+declare(strict_types=1);
+
+namespace App;
+
+use Articus\DataTransfer as DT;
+use OpenAPIGenerator\APIClient as OAGAC;
+use Psr\Http\Client\ClientExceptionInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * OpenAPI Petstore
+ * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+ * The version of the OpenAPI document: 1.0.0
+ */
+class ApiClient extends OAGAC\AbstractApiClient
+{
+    //region addPet
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function addPetRaw(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function addPet(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->addPetRaw($requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 405:
+                /* Invalid input */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function addPetResult(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->addPet($requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region createUser
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUserRaw(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUser(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUserRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUserResult(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->createUser($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region createUsersWithArrayInput
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUsersWithArrayInputRaw(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user/createWithArray', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUsersWithArrayInput(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUsersWithArrayInputRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUsersWithArrayInputResult(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->createUsersWithArrayInput($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region createUsersWithListInput
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUsersWithListInputRaw(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user/createWithList', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUsersWithListInput(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUsersWithListInputRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUsersWithListInputResult(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->createUsersWithListInput($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region deleteOrder
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deleteOrderRaw(
+        \App\DTO\DeleteOrderParameterData $parameters
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/store/order/{orderId}', $this->getPathParameters($parameters), []);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deleteOrder(
+        \App\DTO\DeleteOrderParameterData $parameters
+    ): array
+    {
+        $response = $this->deleteOrderRaw($parameters);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Order not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deleteOrderResult(
+        \App\DTO\DeleteOrderParameterData $parameters
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->deleteOrder($parameters));
+    }
+    //endregion
+
+    //region deletePet
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deletePetRaw(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addCustomHeaders($request, $parameters);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deletePet(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    ): array
+    {
+        $response = $this->deletePetRaw($parameters, $security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid pet value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deletePetResult(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->deletePet($parameters, $security));
+    }
+    //endregion
+
+    //region deleteUser
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deleteUserRaw(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deleteUser(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    ): array
+    {
+        $response = $this->deleteUserRaw($parameters, $security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid username supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deleteUserResult(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->deleteUser($parameters, $security));
+    }
+    //endregion
+
+    //region findPetsByStatus
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function findPetsByStatusRaw(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/findByStatus', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function findPetsByStatus(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->findPetsByStatusRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection19();
+                break;
+            case 400:
+                /* Invalid status value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection19
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function findPetsByStatusResult(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Collection19
+    {
+        return $this->getSuccessfulContent(...$this->findPetsByStatus($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region findPetsByTags
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function findPetsByTagsRaw(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/findByTags', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function findPetsByTags(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->findPetsByTagsRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection26();
+                break;
+            case 400:
+                /* Invalid tag value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection26
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function findPetsByTagsResult(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Collection26
+    {
+        return $this->getSuccessfulContent(...$this->findPetsByTags($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region getInventory
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getInventoryRaw(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/store/inventory', [], []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getInventory(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->getInventoryRaw($security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection34();
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection34
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getInventoryResult(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): \App\DTO\Collection34
+    {
+        return $this->getSuccessfulContent(...$this->getInventory($security, $responseMediaType));
+    }
+    //endregion
+
+    //region getOrderById
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getOrderByIdRaw(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/store/order/{orderId}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getOrderById(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getOrderByIdRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Order();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Order not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return \App\DTO\Order
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getOrderByIdResult(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Order
+    {
+        return $this->getSuccessfulContent(...$this->getOrderById($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region getPetById
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getPetByIdRaw(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getPetById(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getPetByIdRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Pet not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getPetByIdResult(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->getPetById($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region getUserByName
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getUserByNameRaw(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getUserByName(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getUserByNameRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\User();
+                break;
+            case 400:
+                /* Invalid username supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return \App\DTO\User
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getUserByNameResult(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\User
+    {
+        return $this->getSuccessfulContent(...$this->getUserByName($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region loginUser
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function loginUserRaw(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/login', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function loginUser(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->loginUserRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                break;
+            case 400:
+                /* Invalid username/password supplied */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return string
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function loginUserResult(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): string
+    {
+        return $this->getSuccessfulContent(...$this->loginUser($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region logoutUser
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function logoutUserRaw(
+        iterable $security = ['api_key' => []]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/logout', [], []);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function logoutUser(
+        iterable $security = ['api_key' => []]
+    ): array
+    {
+        $response = $this->logoutUserRaw($security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function logoutUserResult(
+        iterable $security = ['api_key' => []]
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->logoutUser($security));
+    }
+    //endregion
+
+    //region placeOrder
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function placeOrderRaw(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/store/order', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function placeOrder(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->placeOrderRaw($requestContent, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Order();
+                break;
+            case 400:
+                /* Invalid Order */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Order
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function placeOrderResult(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Order
+    {
+        return $this->getSuccessfulContent(...$this->placeOrder($requestContent, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region updatePet
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updatePetRaw(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('PUT', '/pet', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updatePet(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->updatePetRaw($requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Pet not found */
+                break;
+            case 405:
+                /* Validation exception */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updatePetResult(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->updatePet($requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region updatePetWithForm
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updatePetWithFormRaw(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updatePetWithForm(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    ): array
+    {
+        $response = $this->updatePetWithFormRaw($parameters, $requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 405:
+                /* Invalid input */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updatePetWithFormResult(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->updatePetWithForm($parameters, $requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region updateUser
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updateUserRaw(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('PUT', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updateUser(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->updateUserRaw($parameters, $requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid user supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updateUserResult(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): mixed
+    {
+        return $this->getSuccessfulContent(...$this->updateUser($parameters, $requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region uploadFile
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function uploadFileRaw(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet/{petId}/uploadImage', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function uploadFile(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->uploadFileRaw($parameters, $requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\ApiResponse();
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\ApiResponse
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function uploadFileResult(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): \App\DTO\ApiResponse
+    {
+        return $this->getSuccessfulContent(...$this->uploadFile($parameters, $requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+}
+
diff --git a/samples/client/petstore/php-dt-modern/src/App/ApiClientFactory.php b/samples/client/petstore/php-dt-modern/src/App/ApiClientFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a1725e7b123abb78b64c849c56540a70553c0aa
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/ApiClientFactory.php
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App;
+
+use Articus\DataTransfer as DT;
+use Interop\Container\ContainerInterface;
+use OpenAPIGenerator\APIClient as OAGAC;
+
+class ApiClientFactory extends DT\ConfigAwareFactory
+{
+    public function __construct(string $configKey = ApiClient::class)
+    {
+        parent::__construct($configKey);
+    }
+
+    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
+    {
+        $config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
+        return new ApiClient(
+            $config->serverUrl,
+            $container->get($config->dataTransferServiceName),
+            $container->get($config->requestFactoryServiceName),
+            $container->get($config->httpClientServiceName),
+            $container->get($config->securityProviderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName)
+        );
+    }
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/ApiResponse.php b/samples/client/petstore/php-dt-modern/src/App/DTO/ApiResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..bfe65906ea50fdcb6f8b91ef0aba2a0d62e72d75
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/ApiResponse.php
@@ -0,0 +1,25 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Describes the result of uploading an image resource
+ */
+class ApiResponse
+{
+    #[DTA\Data(field: "code", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $code = null;
+
+    #[DTA\Data(field: "type", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $type = null;
+
+    #[DTA\Data(field: "message", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $message = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Category.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Category.php
new file mode 100644
index 0000000000000000000000000000000000000000..e6b28c29028e8aafa2d81ea88f3b119ceda5b5eb
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Category.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * A category for a pet
+ */
+class Category
+{
+    #[DTA\Data(field: "id", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $id = null;
+
+    #[DTA\Data(field: "name", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    #[DTA\Validator("Regex", ["pattern" => "/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"])]
+    public string|null $name = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..f0e14da6cd80c3d98817605bfd761a5b0d915046
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection1.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection1.php
new file mode 100644
index 0000000000000000000000000000000000000000..c05da2858bd8dfc79909d770f8cbd0b516e5119c
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection1.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection1 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection10.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection10.php
new file mode 100644
index 0000000000000000000000000000000000000000..29e6ccdb347264347dd4df8c128127e0483f0d17
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection10.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection10 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection11.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection11.php
new file mode 100644
index 0000000000000000000000000000000000000000..89b2d0d01f8a692fa791d1b9dec3c239be5c9672
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection11.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection11 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection12.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection12.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0657b0d467f3d6886013f53ec5b48e2f5e82be8
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection12.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection12 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection13.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection13.php
new file mode 100644
index 0000000000000000000000000000000000000000..26f88d9685ddb16875b9b638f8fc6d7eb2034141
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection13.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection13 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection14.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection14.php
new file mode 100644
index 0000000000000000000000000000000000000000..d1e0e11495b39e5ccca4d4e3525b8be5ed4de694
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection14.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection14 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection15.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection15.php
new file mode 100644
index 0000000000000000000000000000000000000000..085f17e1e9722e2c64c1fe9bd87a8875312f745e
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection15.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection15 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection16.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection16.php
new file mode 100644
index 0000000000000000000000000000000000000000..1b1523c7d09b7eb55aa4883a06400f08740b3d5d
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection16.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection16 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection17.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection17.php
new file mode 100644
index 0000000000000000000000000000000000000000..eb5b0e828f8d6d71ae15d14f8996b22433bded01
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection17.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection17 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection18.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection18.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd55bd5840a7d63ce6aaab2e0861bce484ac216d
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection18.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection18 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection19.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection19.php
new file mode 100644
index 0000000000000000000000000000000000000000..45da36c7301744c228d843452a5645f3ee060365
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection19.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
+]])]
+class Collection19 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection2.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection2.php
new file mode 100644
index 0000000000000000000000000000000000000000..26176dcc5e592ac1b80f8bc81f180f2068ea2f47
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection2.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection2 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection20.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection20.php
new file mode 100644
index 0000000000000000000000000000000000000000..26b16ef104e324de4c21df84116d7b3f5afd25b9
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection20.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection20 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection21.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection21.php
new file mode 100644
index 0000000000000000000000000000000000000000..9e0c2429bde17a1a38f5359788e632c07c98a210
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection21.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection21 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection22.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection22.php
new file mode 100644
index 0000000000000000000000000000000000000000..6f7a04ff4bd9e1713d4cb532e8d41c45c654f8be
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection22.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
+]])]
+class Collection22 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection23.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection23.php
new file mode 100644
index 0000000000000000000000000000000000000000..608c9ad50206646f2a3e0edae02831aeb3a44f3a
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection23.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection23 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection24.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection24.php
new file mode 100644
index 0000000000000000000000000000000000000000..b876816c2ddb568fab158f1366e83c4e766dc5e0
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection24.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection24 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection25.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection25.php
new file mode 100644
index 0000000000000000000000000000000000000000..ad3a8102ad3ee8139a0acc19f58c82be720dfe36
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection25.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection25 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection26.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection26.php
new file mode 100644
index 0000000000000000000000000000000000000000..f8e958fcb402861f7c2d632aac03cf588e760d32
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection26.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
+]])]
+class Collection26 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection27.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection27.php
new file mode 100644
index 0000000000000000000000000000000000000000..b53e9e87a7294d01f10a063324eca6f30b7f7979
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection27.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection27 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection28.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection28.php
new file mode 100644
index 0000000000000000000000000000000000000000..3b6e05419ef1e502e4c306a9a75a59f6575040d4
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection28.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection28 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection29.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection29.php
new file mode 100644
index 0000000000000000000000000000000000000000..24a1ee261d86126417590aecdfc9ac7a06a60d5a
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection29.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Pet::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Pet::class]]
+]])]
+class Collection29 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection3.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection3.php
new file mode 100644
index 0000000000000000000000000000000000000000..1833307cd7e6c8d533c5646e68c8fef8005b448a
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection3.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection3 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection30.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection30.php
new file mode 100644
index 0000000000000000000000000000000000000000..916229afc92ba4820b20252bf1fa29ad71cfbee6
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection30.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection30 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection31.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection31.php
new file mode 100644
index 0000000000000000000000000000000000000000..12b771c1c16a90a8b1f6157e743be53922ca75a7
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection31.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection31 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection32.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection32.php
new file mode 100644
index 0000000000000000000000000000000000000000..e89cbcd4397ab061d5e0bce8cacccedb7d3d52f6
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection32.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection32 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection33.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection33.php
new file mode 100644
index 0000000000000000000000000000000000000000..91229b175cfcce762009f2ac2a9dfe74e01eafa7
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection33.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection33 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection34.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection34.php
new file mode 100644
index 0000000000000000000000000000000000000000..1670c4ee7e3d63673503d4e812d70f1db89f3773
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection34.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarMap", ["type" => "int"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "int"]]
+]])]
+class Collection34 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection35.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection35.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b1082abc1b1381c2b2b549ffe2795ec02cf964f
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection35.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\User::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\User::class]]
+]])]
+class Collection35 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection36.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection36.php
new file mode 100644
index 0000000000000000000000000000000000000000..38595c2f5d398f9b6b41bd9d7fedadaec7eeb4a1
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection36.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\User::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\User::class]]
+]])]
+class Collection36 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection4.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection4.php
new file mode 100644
index 0000000000000000000000000000000000000000..54e2f1a12de5875a45b56742799cdcaa853e30c4
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection4.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection4 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection5.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection5.php
new file mode 100644
index 0000000000000000000000000000000000000000..3f32f4513a7462605494f3f942cc0814d9b6a5e6
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection5.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection5 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection6.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection6.php
new file mode 100644
index 0000000000000000000000000000000000000000..79abc43f3398082f2cbf18c0c065a4f6f0363499
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection6.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection6 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection7.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection7.php
new file mode 100644
index 0000000000000000000000000000000000000000..8574d82b36582574cd95be07afd0faaf4b2e3fff
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection7.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection7 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection8.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection8.php
new file mode 100644
index 0000000000000000000000000000000000000000..c264d8076a1f0f847c546ed0fe181593888cd7eb
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection8.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ScalarList", ["type" => "string"])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "Scalar", "options" => ["type" => "string"]]
+]])]
+class Collection8 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Collection9.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection9.php
new file mode 100644
index 0000000000000000000000000000000000000000..99cc837d6a59f9b9a35adf2f943fbe314e343bb5
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Collection9.php
@@ -0,0 +1,14 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+#[DTA\Strategy("ObjectList", ["type" => \App\DTO\Tag::class])]
+#[DTA\Validator("Collection", ["validators" => [
+    ["name" => "TypeCompliant", "options" => ["type" => \App\DTO\Tag::class]]
+]])]
+class Collection9 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteOrderParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteOrderParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..994c6365c4a103fe3bde9365437965daf19f3d62
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteOrderParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for deleteOrder
+ */
+class DeleteOrderParameterData
+{
+    /**
+     * ID of the order that needs to be deleted
+     */
+    #[DTA\Data(subset: "path", field: "orderId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
+    public string|null $order_id = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/DeletePetParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/DeletePetParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..147a15a512ee519cc51d50518ca83d6c08fec46e
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/DeletePetParameterData.php
@@ -0,0 +1,26 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for deletePet
+ */
+class DeletePetParameterData
+{
+    /**
+     * Pet id to delete
+     */
+    #[DTA\Data(subset: "path", field: "petId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
+    public int|null $pet_id = null;
+
+    #[DTA\Data(subset: "header", field: "api_key", nullable: true)]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "header")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "header")]
+    public string|null $api_key = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteUserParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..1d3caf3bb215324a5e517cf2be400599f2950bcb
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/DeleteUserParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for deleteUser
+ */
+class DeleteUserParameterData
+{
+    /**
+     * The name that needs to be deleted
+     */
+    #[DTA\Data(subset: "path", field: "username")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
+    public string|null $username = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByStatusParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByStatusParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..857a59ed71a4621105f9247fa8a1c5017a3b7db5
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByStatusParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for findPetsByStatus
+ */
+class FindPetsByStatusParameterData
+{
+    /**
+     * Status values that need to be considered for filter
+     */
+    #[DTA\Data(subset: "query", field: "status")]
+    #[DTA\Strategy("QueryStringScalarArray", ["type" => "string", "format" => "csv"], "query")]
+    #[DTA\Validator("QueryStringScalarArray", ["type" => "string", "format" => "csv"], subset: "query")]
+    public array|null $status = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByTagsParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByTagsParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..7a8f0690b903e52c0f38d4fc7b3d05d989fd83b4
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/FindPetsByTagsParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for findPetsByTags
+ */
+class FindPetsByTagsParameterData
+{
+    /**
+     * Tags to filter by
+     */
+    #[DTA\Data(subset: "query", field: "tags")]
+    #[DTA\Strategy("QueryStringScalarArray", ["type" => "string", "format" => "csv"], "query")]
+    #[DTA\Validator("QueryStringScalarArray", ["type" => "string", "format" => "csv"], subset: "query")]
+    public array|null $tags = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/GetOrderByIdParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/GetOrderByIdParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..e31c2dbb2123c0294233555b11505f6681b061c4
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/GetOrderByIdParameterData.php
@@ -0,0 +1,23 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for getOrderById
+ */
+class GetOrderByIdParameterData
+{
+    /**
+     * ID of pet that needs to be fetched
+     */
+    #[DTA\Data(subset: "path", field: "orderId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
+    #[DTA\Validator("GreaterThan", ["min" => 1, "inclusive" => true], subset: "path")]
+    #[DTA\Validator("LessThan", ["max" => 5, "inclusive" => true], subset: "path")]
+    public int|null $order_id = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/GetPetByIdParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/GetPetByIdParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..65921282d402f962827fcf302a317c29da0e03b5
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/GetPetByIdParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for getPetById
+ */
+class GetPetByIdParameterData
+{
+    /**
+     * ID of pet to return
+     */
+    #[DTA\Data(subset: "path", field: "petId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
+    public int|null $pet_id = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/GetUserByNameParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/GetUserByNameParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..b65b1d75e2c955cb1f093a6199f4ba48dc31fdb7
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/GetUserByNameParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for getUserByName
+ */
+class GetUserByNameParameterData
+{
+    /**
+     * The name that needs to be fetched. Use user1 for testing.
+     */
+    #[DTA\Data(subset: "path", field: "username")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
+    public string|null $username = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject.php b/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject.php
new file mode 100644
index 0000000000000000000000000000000000000000..f3cbbf36aea6a362389cf42d63ca541c9db512d1
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject.php
@@ -0,0 +1,24 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+class InlineObject
+{
+    /**
+     * Updated name of the pet
+     */
+    #[DTA\Data(field: "name", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $name = null;
+
+    /**
+     * Updated status of the pet
+     */
+    #[DTA\Data(field: "status", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $status = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject1.php b/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject1.php
new file mode 100644
index 0000000000000000000000000000000000000000..791f4cf410b9bfc0be7740b7746b7cace7e34e6b
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/InlineObject1.php
@@ -0,0 +1,25 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+class InlineObject1
+{
+    /**
+     * Additional data to pass to server
+     */
+    #[DTA\Data(field: "additionalMetadata", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $additional_metadata = null;
+
+    /**
+     * file to upload
+     */
+    #[DTA\Data(field: "file", nullable: true)]
+    #[DTA\Strategy("Object", ["type" => \SplFileObject::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => \SplFileObject::class])]
+    public \SplFileObject|null $file = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/LoginUserParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/LoginUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..508d53f57add8e940bbb0f5c882511b812bae6c5
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/LoginUserParameterData.php
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for loginUser
+ */
+class LoginUserParameterData
+{
+    /**
+     * The password for login in clear text
+     */
+    #[DTA\Data(subset: "query", field: "password")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "query")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "query")]
+    public string|null $password = null;
+
+    /**
+     * The user name for login
+     */
+    #[DTA\Data(subset: "query", field: "username")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "query")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "query")]
+    #[DTA\Validator("Regex", ["pattern" => "/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"], subset: "query")]
+    public string|null $username = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Order.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Order.php
new file mode 100644
index 0000000000000000000000000000000000000000..8dd384b4475db62b54e7a3e63f6580e04f49ae37
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Order.php
@@ -0,0 +1,41 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * An order for a pets from the pet store
+ */
+class Order
+{
+    #[DTA\Data(field: "id", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $id = null;
+
+    #[DTA\Data(field: "petId", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $pet_id = null;
+
+    #[DTA\Data(field: "quantity", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $quantity = null;
+
+    #[DTA\Data(field: "shipDate", nullable: true)]
+    #[DTA\Strategy("DateTime")]
+    #[DTA\Validator("Date", ["format" => \DateTime::RFC3339])]
+    public \DateTime|null $ship_date = null;
+
+    /**
+     * Order Status
+     */
+    #[DTA\Data(field: "status", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $status = null;
+
+    #[DTA\Data(field: "complete", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "bool"])]
+    public bool|null $complete = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Pet.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Pet.php
new file mode 100644
index 0000000000000000000000000000000000000000..bcd5cdb6e8137f772d0717f2bc19a9a70caab4e7
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Pet.php
@@ -0,0 +1,43 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * A pet for sale in the pet store
+ */
+class Pet
+{
+    #[DTA\Data(field: "id", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $id = null;
+
+    #[DTA\Data(field: "category", nullable: true)]
+    #[DTA\Strategy("Object", ["type" => \App\DTO\Category::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Category::class])]
+    public \App\DTO\Category|null $category = null;
+
+    #[DTA\Data(field: "name")]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $name = null;
+
+    #[DTA\Data(field: "photoUrls")]
+    #[DTA\Strategy("Object", ["type" => \App\DTO\Collection32::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Collection32::class])]
+    public \App\DTO\Collection32|null $photo_urls = null;
+
+    #[DTA\Data(field: "tags", nullable: true)]
+    #[DTA\Strategy("Object", ["type" => \App\DTO\Collection33::class])]
+    #[DTA\Validator("TypeCompliant", ["type" => \App\DTO\Collection33::class])]
+    public \App\DTO\Collection33|null $tags = null;
+
+    /**
+     * pet status in the store
+     */
+    #[DTA\Data(field: "status", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $status = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/Tag.php b/samples/client/petstore/php-dt-modern/src/App/DTO/Tag.php
new file mode 100644
index 0000000000000000000000000000000000000000..5fcc6c116b0373e4e6d52d25ac0e05eea89d551f
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/Tag.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * A tag for a pet
+ */
+class Tag
+{
+    #[DTA\Data(field: "id", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $id = null;
+
+    #[DTA\Data(field: "name", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $name = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/UpdatePetWithFormParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/UpdatePetWithFormParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..24849452e92801eceba553f28ad13e08ccda0682
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/UpdatePetWithFormParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for updatePetWithForm
+ */
+class UpdatePetWithFormParameterData
+{
+    /**
+     * ID of pet that needs to be updated
+     */
+    #[DTA\Data(subset: "path", field: "petId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
+    public int|null $pet_id = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/UpdateUserParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/UpdateUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..eaf64f9d7249b9490ccf25fbeb38e5de5b539496
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/UpdateUserParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for updateUser
+ */
+class UpdateUserParameterData
+{
+    /**
+     * name that need to be deleted
+     */
+    #[DTA\Data(subset: "path", field: "username")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "string"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "string"], subset: "path")]
+    public string|null $username = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/UploadFileParameterData.php b/samples/client/petstore/php-dt-modern/src/App/DTO/UploadFileParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..af2bdc4c90577a43abb4d0943ec4182aae10900b
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/UploadFileParameterData.php
@@ -0,0 +1,21 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * Parameters for uploadFile
+ */
+class UploadFileParameterData
+{
+    /**
+     * ID of pet to update
+     */
+    #[DTA\Data(subset: "path", field: "petId")]
+    #[DTA\Strategy("QueryStringScalar", ["type" => "int"], "path")]
+    #[DTA\Validator("QueryStringScalar", ["type" => "int"], subset: "path")]
+    public int|null $pet_id = null;
+
+}
diff --git a/samples/client/petstore/php-dt-modern/src/App/DTO/User.php b/samples/client/petstore/php-dt-modern/src/App/DTO/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..c257dfea3192f3b03978371a67c78f15acc9b9fc
--- /dev/null
+++ b/samples/client/petstore/php-dt-modern/src/App/DTO/User.php
@@ -0,0 +1,48 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\PhpAttribute as DTA;
+
+/**
+ * A User who is purchasing from the pet store
+ */
+class User
+{
+    #[DTA\Data(field: "id", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $id = null;
+
+    #[DTA\Data(field: "username", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $username = null;
+
+    #[DTA\Data(field: "firstName", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $first_name = null;
+
+    #[DTA\Data(field: "lastName", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $last_name = null;
+
+    #[DTA\Data(field: "email", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $email = null;
+
+    #[DTA\Data(field: "password", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $password = null;
+
+    #[DTA\Data(field: "phone", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "string"])]
+    public string|null $phone = null;
+
+    /**
+     * User Status
+     */
+    #[DTA\Data(field: "userStatus", nullable: true)]
+    #[DTA\Validator("Scalar", ["type" => "int"])]
+    public int|null $user_status = null;
+
+}
diff --git a/samples/client/petstore/php-dt/.gitignore b/samples/client/petstore/php-dt/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f674bbd2d1fb689c152c42c93829b1e598be21aa
--- /dev/null
+++ b/samples/client/petstore/php-dt/.gitignore
@@ -0,0 +1,6 @@
+#based on .gitignore generated by https://github.com/zendframework/zend-expressive-skeleton
+.idea
+
+# Composer files
+composer.phar
+vendor/
diff --git a/samples/client/petstore/php-dt/.openapi-generator-ignore b/samples/client/petstore/php-dt/.openapi-generator-ignore
new file mode 100644
index 0000000000000000000000000000000000000000..7484ee590a3894506cf063799b885428f95a71be
--- /dev/null
+++ b/samples/client/petstore/php-dt/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/php-dt/.openapi-generator/FILES b/samples/client/petstore/php-dt/.openapi-generator/FILES
new file mode 100644
index 0000000000000000000000000000000000000000..b1c5f88c6f89a9cf693cc6b477da2a39d440fc4f
--- /dev/null
+++ b/samples/client/petstore/php-dt/.openapi-generator/FILES
@@ -0,0 +1,62 @@
+.gitignore
+README.md
+composer.json
+src/App/ApiClient.php
+src/App/ApiClientFactory.php
+src/App/DTO/ApiResponse.php
+src/App/DTO/Category.php
+src/App/DTO/Collection.php
+src/App/DTO/Collection1.php
+src/App/DTO/Collection10.php
+src/App/DTO/Collection11.php
+src/App/DTO/Collection12.php
+src/App/DTO/Collection13.php
+src/App/DTO/Collection14.php
+src/App/DTO/Collection15.php
+src/App/DTO/Collection16.php
+src/App/DTO/Collection17.php
+src/App/DTO/Collection18.php
+src/App/DTO/Collection19.php
+src/App/DTO/Collection2.php
+src/App/DTO/Collection20.php
+src/App/DTO/Collection21.php
+src/App/DTO/Collection22.php
+src/App/DTO/Collection23.php
+src/App/DTO/Collection24.php
+src/App/DTO/Collection25.php
+src/App/DTO/Collection26.php
+src/App/DTO/Collection27.php
+src/App/DTO/Collection28.php
+src/App/DTO/Collection29.php
+src/App/DTO/Collection3.php
+src/App/DTO/Collection30.php
+src/App/DTO/Collection31.php
+src/App/DTO/Collection32.php
+src/App/DTO/Collection33.php
+src/App/DTO/Collection34.php
+src/App/DTO/Collection35.php
+src/App/DTO/Collection36.php
+src/App/DTO/Collection4.php
+src/App/DTO/Collection5.php
+src/App/DTO/Collection6.php
+src/App/DTO/Collection7.php
+src/App/DTO/Collection8.php
+src/App/DTO/Collection9.php
+src/App/DTO/DeleteOrderParameterData.php
+src/App/DTO/DeletePetParameterData.php
+src/App/DTO/DeleteUserParameterData.php
+src/App/DTO/FindPetsByStatusParameterData.php
+src/App/DTO/FindPetsByTagsParameterData.php
+src/App/DTO/GetOrderByIdParameterData.php
+src/App/DTO/GetPetByIdParameterData.php
+src/App/DTO/GetUserByNameParameterData.php
+src/App/DTO/InlineObject.php
+src/App/DTO/InlineObject1.php
+src/App/DTO/LoginUserParameterData.php
+src/App/DTO/Order.php
+src/App/DTO/Pet.php
+src/App/DTO/Tag.php
+src/App/DTO/UpdatePetWithFormParameterData.php
+src/App/DTO/UpdateUserParameterData.php
+src/App/DTO/UploadFileParameterData.php
+src/App/DTO/User.php
diff --git a/samples/client/petstore/php-dt/.openapi-generator/VERSION b/samples/client/petstore/php-dt/.openapi-generator/VERSION
new file mode 100644
index 0000000000000000000000000000000000000000..862529f8cacd978b63ae68f3674151d549b33168
--- /dev/null
+++ b/samples/client/petstore/php-dt/.openapi-generator/VERSION
@@ -0,0 +1 @@
+5.2.1-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/php-dt/README.md b/samples/client/petstore/php-dt/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..62fd55096c2436e8fa018f4d9c7c60f090ad3a46
--- /dev/null
+++ b/samples/client/petstore/php-dt/README.md
@@ -0,0 +1,135 @@
+# Client library for OpenAPI Petstore
+
+Generated by the [OpenAPI Generator](https://openapi-generator.tech) project.
+
+## Overview
+This lightweight extensible client library is [PSR-7](https://www.php-fig.org/psr/psr-7), [PSR-11](https://www.php-fig.org/psr/psr-11), [PSR-17](https://www.php-fig.org/psr/psr-17) and [PSR-18](https://www.php-fig.org/psr/psr-18) complaint and relies on:
+
+- PHP: >=7.3
+- [Data Transfer](https://github.com/Articus/DataTransfer): >=0.5
+
+
+## How to use
+
+This library can be used either as a separate package (just deploy generated files to your package repository and add dependency `"git_user_id/git_repo_id":"1.0.0"` to your project `composer.json`) or as a part of your project (just copy generated code from `src` and merge generated `composer.json` into your project `composer.json`).
+
+First you need an implementation for [PSR-7](https://packagist.org/packages/psr/http-message) and [PSR-17](https://packagist.org/packages/psr/http-factory) interfaces. Usually it is a single package, and your project might already have one among its dependencies (for example if it is some web service). Otherwise, https://packagist.org/providers/psr/http-message-implementation and https://packagist.org/providers/psr/http-factory-implementation may help to find some suitable options.
+
+Next choose an implementation for [PSR-18 interfaces](https://packagist.org/packages/psr/http-client). https://packagist.org/providers/psr/http-client-implementation may help to find some suitable options.
+
+Then check content types for API requests you intend to send and API responses you intend to receive. For each unique content type you will need an implementation of [`OpenAPIGenerator\APIClient\BodyCoderInterface`](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoderInterface.php) to encode request bodies and decode response bodies. Currently, only [`application/json` body coder](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/BodyCoder/Json.php) is provided out-of-the-box.
+
+After that review security requirements for API operations you intend to use. For each unique security scheme you will need an implementation of [OpenAPIGenerator\APIClient\SecurityProviderInterface](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProviderInterface.php). Currently, only [HTTP Bearer authentication](https://github.com/Articus/OpenAPIGeneratorAPIClient-PHP/blob/master/src/OpenAPIGenerator/APIClient/SecurityProvider/HttpBearer.php) is supported out-of-the-box.
+
+The last step is to configure and wire all services together. It is highly advisable to use [PSR-11 container](https://packagist.org/packages/psr/container) for that. If you have not selected one for your project yet, https://packagist.org/providers/psr/container-implementation may help to find some suitable options. Here is a sample wiring configuration for `"laminas/laminas-servicemanager"`, `"laminas/laminas-diactoros"` and `"symfony/http-client"` (consult generated `composer.json` for the exact versions of used packages):
+
+```PHP
+<?php
+declare(strict_types=1);
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+$dependencies = [
+    'invokables' => [
+        Psr\Http\Message\RequestFactoryInterface::class => Laminas\Diactoros\RequestFactory::class,
+        Psr\Http\Message\ResponseFactoryInterface::class => Laminas\Diactoros\ResponseFactory::class,
+        Psr\Http\Message\StreamFactoryInterface::class => Laminas\Diactoros\StreamFactory::class,
+    ],
+    'factories' => [
+        App\ApiClient::class => App\ApiClientFactory::class,
+
+        Articus\DataTransfer\Service::class => Articus\DataTransfer\Factory::class,
+        Articus\DataTransfer\MetadataProvider\Annotation::class => Articus\DataTransfer\MetadataProvider\Factory\Annotation::class,
+        Articus\DataTransfer\Strategy\PluginManager::class => Articus\DataTransfer\Strategy\Factory\PluginManager::class,
+        Articus\DataTransfer\Validator\PluginManager::class => Articus\DataTransfer\Validator\Factory\PluginManager::class,
+        Laminas\Validator\ValidatorPluginManager::class => Laminas\Validator\ValidatorPluginManagerFactory::class,
+
+        OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => OpenAPIGenerator\APIClient\SecurityProvider\Factory\PluginManager::class,
+        OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => OpenAPIGenerator\APIClient\BodyCoder\Factory\PluginManager::class,
+
+        Psr\Http\Client\ClientInterface::class => function (Psr\Container\ContainerInterface $container)
+        {
+            return new Symfony\Component\HttpClient\Psr18Client(
+                new Symfony\Component\HttpClient\NativeHttpClient(),
+                $container->get(Psr\Http\Message\ResponseFactoryInterface::class),
+                $container->get(Psr\Http\Message\StreamFactoryInterface::class)
+            );
+        },
+    ],
+    'aliases' => [
+        Articus\DataTransfer\ClassMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
+        Articus\DataTransfer\FieldMetadataProviderInterface::class => Articus\DataTransfer\MetadataProvider\Annotation::class,
+    ],
+];
+$config = [
+    'dependencies' => $dependencies,
+
+    //Configure DataTransfer library
+    Articus\DataTransfer\Strategy\PluginManager::class => [
+        'invokables' => [
+            'QueryStringScalar' => OpenAPIGenerator\Common\Strategy\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Strategy\QueryStringScalarArray::class,
+        ],
+          'factories' => [
+            'Date' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDate::class,
+            'DateTime' => OpenAPIGenerator\Common\Strategy\Factory\ImmutableDateTime::class,
+            'ObjectList' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectList::class,
+            'ObjectMap' => OpenAPIGenerator\Common\Strategy\Factory\NoArgObjectMap::class,
+            'ScalarList' => OpenAPIGenerator\Common\Strategy\Factory\ScalarList::class,
+            'ScalarMap' => OpenAPIGenerator\Common\Strategy\Factory\ScalarMap::class,
+        ]
+    ],
+    Articus\DataTransfer\Validator\PluginManager::class => [
+        'invokables' => [
+            'Scalar' => OpenAPIGenerator\Common\Validator\Scalar::class,
+            'QueryStringScalar' => OpenAPIGenerator\Common\Validator\QueryStringScalar::class,
+            'QueryStringScalarArray' => OpenAPIGenerator\Common\Validator\QueryStringScalarArray::class,
+        ],
+        'abstract_factories' => [
+            Articus\DataTransfer\Validator\Factory\Laminas::class,
+        ],
+    ],
+    'validators' => [
+        'invokables' => [
+            'Count' => Laminas\Validator\IsCountable::class,
+        ],
+    ],
+
+    //Set API server URL here
+    App\ApiClient::class => [
+        //'server_url' => 'https://api.url',
+    ],
+
+    //Register body coders for used content types here
+    OpenAPIGenerator\APIClient\BodyCoder\PluginManager::class => [
+        'factories' => [
+            //'another/mime-type' => AnotherMimeTypeBodyCoder::class
+        ],
+    ],
+
+    //Register security providers for used security schemes here
+    OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class => [
+        'factories' => [
+            //'another-security-scheme' => AnotherSecuritySchemeProvider::class,
+        ],
+        'aliases' => [
+            //'custom-name-for-htt-bearer' => OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class,
+        ],
+    ],
+];
+$container = new Laminas\ServiceManager\ServiceManager($dependencies);
+$container->setService('config', $config);
+$container->setAlias('Config', 'config');
+
+/** @var App\ApiClient $client */
+$client = $container->get(App\ApiClient::class);
+//... and now you can use client methods to call API operations :)
+
+//And one more sample: how to set token for HTTP Bearer authentication
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\PluginManager $securityProviders */
+$securityProviders = $container->get(OpenAPIGenerator\APIClient\SecurityProvider\PluginManager::class);
+/** @var OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer $httpBearer */
+$httpBearer = $securityProviders->get(OpenAPIGenerator\APIClient\SecurityProvider\HttpBearer::class);
+$httpBearer->setToken('some-token');
+
+```
diff --git a/samples/client/petstore/php-dt/composer.json b/samples/client/petstore/php-dt/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..e50aa59117e510fc8a12e137f47a523ab0ec9aed
--- /dev/null
+++ b/samples/client/petstore/php-dt/composer.json
@@ -0,0 +1,27 @@
+{
+    "name": "git_user_id/git_repo_id",
+    "description": "",
+    "license": "unlicense",
+    "version": "1.0.0",
+    "type": "library",
+    "require": {
+        "php": "^7.3 || ^8.0",
+        "articus/data-transfer": "^0.5",
+        "articus/openapi-generator-common": "^0.2",
+        "articus/openapi-generator-apiclient": "^0.1",
+        "doctrine/annotations": "^1.10",
+        "psr/simple-cache": "^1.0",
+        "laminas/laminas-stdlib": "^3.2",
+        "laminas/laminas-validator": "^2.13"
+    },
+    "autoload": {
+        "psr-4": {
+            "": "src/"
+        }
+    },
+    "require-dev": {
+        "laminas/laminas-servicemanager": "^3.6",
+        "laminas/laminas-diactoros": "^2.6",
+        "symfony/http-client": "^5.3"
+    }
+}
\ No newline at end of file
diff --git a/samples/client/petstore/php-dt/src/App/ApiClient.php b/samples/client/petstore/php-dt/src/App/ApiClient.php
new file mode 100644
index 0000000000000000000000000000000000000000..2ad89d55ad64d487717165f534c45248120e9db2
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/ApiClient.php
@@ -0,0 +1,1471 @@
+<?php
+declare(strict_types=1);
+
+namespace App;
+
+use Articus\DataTransfer as DT;
+use OpenAPIGenerator\APIClient as OAGAC;
+use Psr\Http\Client\ClientExceptionInterface;
+use Psr\Http\Message\ResponseInterface;
+
+/**
+ * OpenAPI Petstore
+ * This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+ * The version of the OpenAPI document: 1.0.0
+ */
+class ApiClient extends OAGAC\AbstractApiClient
+{
+    //region addPet
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function addPetRaw(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function addPet(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->addPetRaw($requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 405:
+                /* Invalid input */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Add a new pet to the store
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function addPetResult(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->addPet($requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region createUser
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUserRaw(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUser(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUserRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Create user
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUserResult(
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    )
+    {
+        return $this->getSuccessfulContent(...$this->createUser($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region createUsersWithArrayInput
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUsersWithArrayInputRaw(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user/createWithArray', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUsersWithArrayInput(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUsersWithArrayInputRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUsersWithArrayInputResult(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    )
+    {
+        return $this->getSuccessfulContent(...$this->createUsersWithArrayInput($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region createUsersWithListInput
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function createUsersWithListInputRaw(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/user/createWithList', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function createUsersWithListInput(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->createUsersWithListInputRaw($requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Creates list of users with given input array
+     * @param \App\DTO\Collection36 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function createUsersWithListInputResult(
+        \App\DTO\Collection36 $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    )
+    {
+        return $this->getSuccessfulContent(...$this->createUsersWithListInput($requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region deleteOrder
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deleteOrderRaw(
+        \App\DTO\DeleteOrderParameterData $parameters
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/store/order/{orderId}', $this->getPathParameters($parameters), []);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deleteOrder(
+        \App\DTO\DeleteOrderParameterData $parameters
+    ): array
+    {
+        $response = $this->deleteOrderRaw($parameters);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Order not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Delete purchase order by ID
+     * @param \App\DTO\DeleteOrderParameterData $parameters
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deleteOrderResult(
+        \App\DTO\DeleteOrderParameterData $parameters
+    )
+    {
+        return $this->getSuccessfulContent(...$this->deleteOrder($parameters));
+    }
+    //endregion
+
+    //region deletePet
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deletePetRaw(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addCustomHeaders($request, $parameters);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deletePet(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    ): array
+    {
+        $response = $this->deletePetRaw($parameters, $security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid pet value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Deletes a pet
+     * @param \App\DTO\DeletePetParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deletePetResult(
+        \App\DTO\DeletePetParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]]
+    )
+    {
+        return $this->getSuccessfulContent(...$this->deletePet($parameters, $security));
+    }
+    //endregion
+
+    //region deleteUser
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function deleteUserRaw(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('DELETE', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function deleteUser(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    ): array
+    {
+        $response = $this->deleteUserRaw($parameters, $security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid username supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Delete user
+     * @param \App\DTO\DeleteUserParameterData $parameters
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function deleteUserResult(
+        \App\DTO\DeleteUserParameterData $parameters,
+        iterable $security = ['api_key' => []]
+    )
+    {
+        return $this->getSuccessfulContent(...$this->deleteUser($parameters, $security));
+    }
+    //endregion
+
+    //region findPetsByStatus
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function findPetsByStatusRaw(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/findByStatus', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function findPetsByStatus(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->findPetsByStatusRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection19();
+                break;
+            case 400:
+                /* Invalid status value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Finds Pets by status
+     * @param \App\DTO\FindPetsByStatusParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection19
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function findPetsByStatusResult(
+        \App\DTO\FindPetsByStatusParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Collection19
+    {
+        return $this->getSuccessfulContent(...$this->findPetsByStatus($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region findPetsByTags
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function findPetsByTagsRaw(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/findByTags', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function findPetsByTags(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->findPetsByTagsRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection26();
+                break;
+            case 400:
+                /* Invalid tag value */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Finds Pets by tags
+     * @param \App\DTO\FindPetsByTagsParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection26
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function findPetsByTagsResult(
+        \App\DTO\FindPetsByTagsParameterData $parameters,
+        iterable $security = ['petstore_auth' => ['read:pets', ]],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Collection26
+    {
+        return $this->getSuccessfulContent(...$this->findPetsByTags($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region getInventory
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getInventoryRaw(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/store/inventory', [], []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getInventory(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->getInventoryRaw($security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Collection34();
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Returns pet inventories by status
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Collection34
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getInventoryResult(
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/json'
+    ): \App\DTO\Collection34
+    {
+        return $this->getSuccessfulContent(...$this->getInventory($security, $responseMediaType));
+    }
+    //endregion
+
+    //region getOrderById
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getOrderByIdRaw(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/store/order/{orderId}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getOrderById(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getOrderByIdRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Order();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Order not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Find purchase order by ID
+     * @param \App\DTO\GetOrderByIdParameterData $parameters
+     * @param string $responseMediaType
+     * @return \App\DTO\Order
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getOrderByIdResult(
+        \App\DTO\GetOrderByIdParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Order
+    {
+        return $this->getSuccessfulContent(...$this->getOrderById($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region getPetById
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getPetByIdRaw(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getPetById(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getPetByIdRaw($parameters, $security, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Pet not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Find pet by ID
+     * @param \App\DTO\GetPetByIdParameterData $parameters
+     * @param iterable|string[][] $security
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getPetByIdResult(
+        \App\DTO\GetPetByIdParameterData $parameters,
+        iterable $security = ['api_key' => []],
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->getPetById($parameters, $security, $responseMediaType));
+    }
+    //endregion
+
+    //region getUserByName
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function getUserByNameRaw(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function getUserByName(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->getUserByNameRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\User();
+                break;
+            case 400:
+                /* Invalid username supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Get user by user name
+     * @param \App\DTO\GetUserByNameParameterData $parameters
+     * @param string $responseMediaType
+     * @return \App\DTO\User
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function getUserByNameResult(
+        \App\DTO\GetUserByNameParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\User
+    {
+        return $this->getSuccessfulContent(...$this->getUserByName($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region loginUser
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function loginUserRaw(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/login', [], $this->getQueryParameters($parameters));
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function loginUser(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->loginUserRaw($parameters, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                break;
+            case 400:
+                /* Invalid username/password supplied */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Logs user into the system
+     * @param \App\DTO\LoginUserParameterData $parameters
+     * @param string $responseMediaType
+     * @return string
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function loginUserResult(
+        \App\DTO\LoginUserParameterData $parameters,
+        string $responseMediaType = 'application/xml'
+    ): string
+    {
+        return $this->getSuccessfulContent(...$this->loginUser($parameters, $responseMediaType));
+    }
+    //endregion
+
+    //region logoutUser
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function logoutUserRaw(
+        iterable $security = ['api_key' => []]
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('GET', '/user/logout', [], []);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function logoutUser(
+        iterable $security = ['api_key' => []]
+    ): array
+    {
+        $response = $this->logoutUserRaw($security);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            default:
+                /* successful operation */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Logs out current logged in user session
+     * @param iterable|string[][] $security
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function logoutUserResult(
+        iterable $security = ['api_key' => []]
+    )
+    {
+        return $this->getSuccessfulContent(...$this->logoutUser($security));
+    }
+    //endregion
+
+    //region placeOrder
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function placeOrderRaw(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/store/order', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function placeOrder(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->placeOrderRaw($requestContent, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Order();
+                break;
+            case 400:
+                /* Invalid Order */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Place an order for a pet
+     * @param \App\DTO\Order $requestContent
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Order
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function placeOrderResult(
+        \App\DTO\Order $requestContent,
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Order
+    {
+        return $this->getSuccessfulContent(...$this->placeOrder($requestContent, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region updatePet
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updatePetRaw(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('PUT', '/pet', [], []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updatePet(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): array
+    {
+        $response = $this->updatePetRaw($requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\Pet();
+                break;
+            case 400:
+                /* Invalid ID supplied */
+                break;
+            case 404:
+                /* Pet not found */
+                break;
+            case 405:
+                /* Validation exception */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Update an existing pet
+     * @param \App\DTO\Pet $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\Pet
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updatePetResult(
+        \App\DTO\Pet $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/json',
+        string $responseMediaType = 'application/xml'
+    ): \App\DTO\Pet
+    {
+        return $this->getSuccessfulContent(...$this->updatePet($requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+
+    //region updatePetWithForm
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updatePetWithFormRaw(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet/{petId}', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updatePetWithForm(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    ): array
+    {
+        $response = $this->updatePetWithFormRaw($parameters, $requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 405:
+                /* Invalid input */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Updates a pet in the store with form data
+     * @param \App\DTO\UpdatePetWithFormParameterData $parameters
+     * @param \App\DTO\InlineObject $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updatePetWithFormResult(
+        \App\DTO\UpdatePetWithFormParameterData $parameters,
+        \App\DTO\InlineObject $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'application/x-www-form-urlencoded'
+    )
+    {
+        return $this->getSuccessfulContent(...$this->updatePetWithForm($parameters, $requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region updateUser
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function updateUserRaw(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('PUT', '/user/{username}', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function updateUser(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->updateUserRaw($parameters, $requestContent, $security, $requestMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 400:
+                /* Invalid user supplied */
+                break;
+            case 404:
+                /* User not found */
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * Updated user
+     * @param \App\DTO\UpdateUserParameterData $parameters
+     * @param \App\DTO\User $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @return mixed
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function updateUserResult(
+        \App\DTO\UpdateUserParameterData $parameters,
+        \App\DTO\User $requestContent,
+        iterable $security = ['api_key' => []],
+        string $requestMediaType = 'application/json'
+    )
+    {
+        return $this->getSuccessfulContent(...$this->updateUser($parameters, $requestContent, $security, $requestMediaType));
+    }
+    //endregion
+
+    //region uploadFile
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return ResponseInterface
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     */
+    public function uploadFileRaw(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): ResponseInterface
+    {
+        $request = $this->createRequest('POST', '/pet/{petId}/uploadImage', $this->getPathParameters($parameters), []);
+        $request = $this->addBody($request, $requestMediaType, $requestContent);
+        $request = $this->addAcceptHeader($request, $responseMediaType);
+        $request = $this->addSecurity($request, $security);
+        return $this->httpClient->sendRequest($request);
+    }
+
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return array
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     */
+    public function uploadFile(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): array
+    {
+        $response = $this->uploadFileRaw($parameters, $requestContent, $security, $requestMediaType, $responseMediaType);
+        $responseContent = null;
+        switch ($response->getStatusCode())
+        {
+            case 200:
+                /* successful operation */
+                $responseContent = new \App\DTO\ApiResponse();
+                break;
+        }
+        $this->parseBody($response, $responseContent);
+        return [$responseContent, $response->getHeaders(), $response->getStatusCode(), $response->getReasonPhrase()];
+    }
+
+    /**
+     * uploads an image
+     * @param \App\DTO\UploadFileParameterData $parameters
+     * @param \App\DTO\InlineObject1 $requestContent
+     * @param iterable|string[][] $security
+     * @param string $requestMediaType
+     * @param string $responseMediaType
+     * @return \App\DTO\ApiResponse
+     * @throws ClientExceptionInterface
+     * @throws DT\Exception\InvalidData
+     * @throws OAGAC\Exception\InvalidResponseBodySchema
+     * @throws OAGAC\Exception\UnsuccessfulResponse
+     */
+    public function uploadFileResult(
+        \App\DTO\UploadFileParameterData $parameters,
+        \App\DTO\InlineObject1 $requestContent,
+        iterable $security = ['petstore_auth' => ['write:pets', 'read:pets', ]],
+        string $requestMediaType = 'multipart/form-data',
+        string $responseMediaType = 'application/json'
+    ): \App\DTO\ApiResponse
+    {
+        return $this->getSuccessfulContent(...$this->uploadFile($parameters, $requestContent, $security, $requestMediaType, $responseMediaType));
+    }
+    //endregion
+}
+
diff --git a/samples/client/petstore/php-dt/src/App/ApiClientFactory.php b/samples/client/petstore/php-dt/src/App/ApiClientFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a1725e7b123abb78b64c849c56540a70553c0aa
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/ApiClientFactory.php
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App;
+
+use Articus\DataTransfer as DT;
+use Interop\Container\ContainerInterface;
+use OpenAPIGenerator\APIClient as OAGAC;
+
+class ApiClientFactory extends DT\ConfigAwareFactory
+{
+    public function __construct(string $configKey = ApiClient::class)
+    {
+        parent::__construct($configKey);
+    }
+
+    public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
+    {
+        $config = new OAGAC\ApiClientOptions(\array_merge($this->getServiceConfig($container), $options ?? []));
+        return new ApiClient(
+            $config->serverUrl,
+            $container->get($config->dataTransferServiceName),
+            $container->get($config->requestFactoryServiceName),
+            $container->get($config->httpClientServiceName),
+            $container->get($config->securityProviderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName),
+            $container->get($config->bodyCoderFactoryServiceName)
+        );
+    }
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/ApiResponse.php b/samples/client/petstore/php-dt/src/App/DTO/ApiResponse.php
new file mode 100644
index 0000000000000000000000000000000000000000..0161f75b2b296b481ab5777f18d7c0b0358138af
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/ApiResponse.php
@@ -0,0 +1,34 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Describes the result of uploading an image resource
+ */
+class ApiResponse
+{
+    /**
+     * @DTA\Data(field="code", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $code;
+
+    /**
+     * @DTA\Data(field="type", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $type;
+
+    /**
+     * @DTA\Data(field="message", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $message;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Category.php b/samples/client/petstore/php-dt/src/App/DTO/Category.php
new file mode 100644
index 0000000000000000000000000000000000000000..41a221be1cf75f809dd5fe053741c15dad301893
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Category.php
@@ -0,0 +1,28 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * A category for a pet
+ */
+class Category
+{
+    /**
+     * @DTA\Data(field="id", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $id;
+
+    /**
+     * @DTA\Data(field="name", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @DTA\Validator(name="Regex", options={"pattern":"/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"})
+     * @var string|null
+     */
+    public $name;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection.php b/samples/client/petstore/php-dt/src/App/DTO/Collection.php
new file mode 100644
index 0000000000000000000000000000000000000000..0e478eb4bd8e6288e6d8cf360f4cbc36068f6c87
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection1.php b/samples/client/petstore/php-dt/src/App/DTO/Collection1.php
new file mode 100644
index 0000000000000000000000000000000000000000..b0343c54df80db6b64bd4d36ab6f98014ef2362b
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection1.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection1 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection10.php b/samples/client/petstore/php-dt/src/App/DTO/Collection10.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a9e490dcbb04404f111f1790bedad54b28cb7d6
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection10.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection10 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection11.php b/samples/client/petstore/php-dt/src/App/DTO/Collection11.php
new file mode 100644
index 0000000000000000000000000000000000000000..438fd641ee0b61e00434293d81383cc9ce214b76
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection11.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection11 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection12.php b/samples/client/petstore/php-dt/src/App/DTO/Collection12.php
new file mode 100644
index 0000000000000000000000000000000000000000..42026632bf5efb31e2464ffe5c353ee7a39874e9
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection12.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection12 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection13.php b/samples/client/petstore/php-dt/src/App/DTO/Collection13.php
new file mode 100644
index 0000000000000000000000000000000000000000..b6c2c328d6f0f24e901d6d54d0d26d2f162f95ed
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection13.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection13 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection14.php b/samples/client/petstore/php-dt/src/App/DTO/Collection14.php
new file mode 100644
index 0000000000000000000000000000000000000000..8185ac10af3647444d9181519ff5ba69c85be299
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection14.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection14 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection15.php b/samples/client/petstore/php-dt/src/App/DTO/Collection15.php
new file mode 100644
index 0000000000000000000000000000000000000000..0d0f70ab9fd791bfce8d7459788c2784dd903c52
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection15.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection15 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection16.php b/samples/client/petstore/php-dt/src/App/DTO/Collection16.php
new file mode 100644
index 0000000000000000000000000000000000000000..11cea21545160f1ba9e84ff461ec76cf8f01d170
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection16.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection16 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection17.php b/samples/client/petstore/php-dt/src/App/DTO/Collection17.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ea21bcf4e2ad60936a432d963a37792bb10b915
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection17.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection17 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection18.php b/samples/client/petstore/php-dt/src/App/DTO/Collection18.php
new file mode 100644
index 0000000000000000000000000000000000000000..592876e132e38ccc3d1a9482f97e5d6c53ce0130
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection18.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection18 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection19.php b/samples/client/petstore/php-dt/src/App/DTO/Collection19.php
new file mode 100644
index 0000000000000000000000000000000000000000..80246c605e0bdbf6f15fd6d8cf713eba37bd80d4
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection19.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Pet::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Pet::class}}
+ * }})
+ */
+class Collection19 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection2.php b/samples/client/petstore/php-dt/src/App/DTO/Collection2.php
new file mode 100644
index 0000000000000000000000000000000000000000..84fa3ea01820a1a014af91139e7c62fa8332efa7
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection2.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection2 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection20.php b/samples/client/petstore/php-dt/src/App/DTO/Collection20.php
new file mode 100644
index 0000000000000000000000000000000000000000..ac9e5aa11836286db1dc44a580b33265dda95e51
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection20.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection20 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection21.php b/samples/client/petstore/php-dt/src/App/DTO/Collection21.php
new file mode 100644
index 0000000000000000000000000000000000000000..ee7a0e5eb57297bb064cee535267e04e58e30838
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection21.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection21 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection22.php b/samples/client/petstore/php-dt/src/App/DTO/Collection22.php
new file mode 100644
index 0000000000000000000000000000000000000000..f45c3f1f1a1861be1cd66916069360243e0d0aee
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection22.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Pet::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Pet::class}}
+ * }})
+ */
+class Collection22 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection23.php b/samples/client/petstore/php-dt/src/App/DTO/Collection23.php
new file mode 100644
index 0000000000000000000000000000000000000000..e716a7ccb5acdda162987677d2b5c038c754b20d
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection23.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection23 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection24.php b/samples/client/petstore/php-dt/src/App/DTO/Collection24.php
new file mode 100644
index 0000000000000000000000000000000000000000..423232d3aeed51fc49f112bd975f6a6f8a1f1126
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection24.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection24 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection25.php b/samples/client/petstore/php-dt/src/App/DTO/Collection25.php
new file mode 100644
index 0000000000000000000000000000000000000000..8cc9f56843a89f1e560c1e6bc5b2d0da8e35fc6f
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection25.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection25 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection26.php b/samples/client/petstore/php-dt/src/App/DTO/Collection26.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c85b7098b05c01c66f7e7c967dbdb0d99c7f760
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection26.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Pet::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Pet::class}}
+ * }})
+ */
+class Collection26 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection27.php b/samples/client/petstore/php-dt/src/App/DTO/Collection27.php
new file mode 100644
index 0000000000000000000000000000000000000000..00018f2b29c880d63c091cda6fa7ed46075ef649
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection27.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection27 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection28.php b/samples/client/petstore/php-dt/src/App/DTO/Collection28.php
new file mode 100644
index 0000000000000000000000000000000000000000..61d50cccccdca8e82fc561fbe72124514be0dd72
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection28.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection28 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection29.php b/samples/client/petstore/php-dt/src/App/DTO/Collection29.php
new file mode 100644
index 0000000000000000000000000000000000000000..e31a37bb81f0db8c7489a2fdf3cfb514fdf2fa27
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection29.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Pet::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Pet::class}}
+ * }})
+ */
+class Collection29 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection3.php b/samples/client/petstore/php-dt/src/App/DTO/Collection3.php
new file mode 100644
index 0000000000000000000000000000000000000000..06a21d321852998198a82818cb7dde527654d8c3
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection3.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection3 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection30.php b/samples/client/petstore/php-dt/src/App/DTO/Collection30.php
new file mode 100644
index 0000000000000000000000000000000000000000..a663f70d213baf7aa8298244a02752abfd8e33cb
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection30.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection30 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection31.php b/samples/client/petstore/php-dt/src/App/DTO/Collection31.php
new file mode 100644
index 0000000000000000000000000000000000000000..3a3fa85b1939ae29372df21b47ea2ca2ffc72a23
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection31.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection31 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection32.php b/samples/client/petstore/php-dt/src/App/DTO/Collection32.php
new file mode 100644
index 0000000000000000000000000000000000000000..b55eb2fe3fa1b51f4ab4af3b8a42748424138cb2
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection32.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection32 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection33.php b/samples/client/petstore/php-dt/src/App/DTO/Collection33.php
new file mode 100644
index 0000000000000000000000000000000000000000..c185ea1732abcf4aaa89439ea4c4255a66d24fec
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection33.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection33 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection34.php b/samples/client/petstore/php-dt/src/App/DTO/Collection34.php
new file mode 100644
index 0000000000000000000000000000000000000000..bab1f0c8378be57cbae50c65f527c32e6748267d
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection34.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarMap", options={"type":"int"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"int"}}
+ * }})
+ */
+class Collection34 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection35.php b/samples/client/petstore/php-dt/src/App/DTO/Collection35.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fbdf64433d8069c7e198b464a2ab64cc471e4da
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection35.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\User::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\User::class}}
+ * }})
+ */
+class Collection35 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection36.php b/samples/client/petstore/php-dt/src/App/DTO/Collection36.php
new file mode 100644
index 0000000000000000000000000000000000000000..b4de3975fa21215f6db427876e739817587cd76e
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection36.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\User::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\User::class}}
+ * }})
+ */
+class Collection36 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection4.php b/samples/client/petstore/php-dt/src/App/DTO/Collection4.php
new file mode 100644
index 0000000000000000000000000000000000000000..7bf0b3d5ebc1540e2da44dc07ad5108d473da848
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection4.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection4 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection5.php b/samples/client/petstore/php-dt/src/App/DTO/Collection5.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9a6420076252ead6081f8be955e8a4311a62e62
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection5.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection5 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection6.php b/samples/client/petstore/php-dt/src/App/DTO/Collection6.php
new file mode 100644
index 0000000000000000000000000000000000000000..4861af08f51171754ec6c75095c5d5c8178dcf4f
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection6.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection6 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection7.php b/samples/client/petstore/php-dt/src/App/DTO/Collection7.php
new file mode 100644
index 0000000000000000000000000000000000000000..77fc5ea821ed50d4855d1d2c5ea72154aa2c04e2
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection7.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection7 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection8.php b/samples/client/petstore/php-dt/src/App/DTO/Collection8.php
new file mode 100644
index 0000000000000000000000000000000000000000..7cc50f8c58d9c2f269a4489ab4ea4e4f53c81648
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection8.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ScalarList", options={"type":"string"})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"Scalar", "options":{"type":"string"}}
+ * }})
+ */
+class Collection8 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Collection9.php b/samples/client/petstore/php-dt/src/App/DTO/Collection9.php
new file mode 100644
index 0000000000000000000000000000000000000000..218d5f6352780abf0d5cb1893fd3e1ad1e4a6d41
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Collection9.php
@@ -0,0 +1,16 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * @DTA\Strategy(name="ObjectList", options={"type":\App\DTO\Tag::class})
+ * @DTA\Validator(name="Collection", options={"validators":{
+ *     {"name":"TypeCompliant", "options":{"type":\App\DTO\Tag::class}}
+ * }})
+ */
+class Collection9 extends \ArrayObject
+{
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/DeleteOrderParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/DeleteOrderParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..b9e2704fa87f95530cc43454e59e5482b38451ef
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/DeleteOrderParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for deleteOrder
+ */
+class DeleteOrderParameterData
+{
+    /**
+     * ID of the order that needs to be deleted
+     * @DTA\Data(subset="path", field="orderId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $order_id;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/DeletePetParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/DeletePetParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..159aa09fe411f6d3de0c49700c04901444bb1cfe
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/DeletePetParameterData.php
@@ -0,0 +1,30 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for deletePet
+ */
+class DeletePetParameterData
+{
+    /**
+     * Pet id to delete
+     * @DTA\Data(subset="path", field="petId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $pet_id;
+
+    /**
+     * @DTA\Data(subset="header", field="api_key", nullable=true)
+     * @DTA\Strategy(subset="header", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="header", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $api_key;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/DeleteUserParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/DeleteUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..8c239c618dff0bf1bc5f3d8c50e425861362523e
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/DeleteUserParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for deleteUser
+ */
+class DeleteUserParameterData
+{
+    /**
+     * The name that needs to be deleted
+     * @DTA\Data(subset="path", field="username")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $username;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/FindPetsByStatusParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/FindPetsByStatusParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..33c4e9a840f0423c360c9f30bc43783996cd114b
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/FindPetsByStatusParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for findPetsByStatus
+ */
+class FindPetsByStatusParameterData
+{
+    /**
+     * Status values that need to be considered for filter
+     * @DTA\Data(subset="query", field="status")
+     * @DTA\Strategy(subset="query", name="QueryStringScalarArray", options={"type":"string", "format":"csv"})
+     * @DTA\Validator(subset="query", name="QueryStringScalarArray", options={"type":"string", "format":"csv"})
+     * @var string[]|null
+     */
+    public $status;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/FindPetsByTagsParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/FindPetsByTagsParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..bde4861a8a8d5592d912c0904465aaf28dab660e
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/FindPetsByTagsParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for findPetsByTags
+ */
+class FindPetsByTagsParameterData
+{
+    /**
+     * Tags to filter by
+     * @DTA\Data(subset="query", field="tags")
+     * @DTA\Strategy(subset="query", name="QueryStringScalarArray", options={"type":"string", "format":"csv"})
+     * @DTA\Validator(subset="query", name="QueryStringScalarArray", options={"type":"string", "format":"csv"})
+     * @var string[]|null
+     */
+    public $tags;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/GetOrderByIdParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/GetOrderByIdParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..c703c223d36bd71502d388bf070195ce8249ebe8
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/GetOrderByIdParameterData.php
@@ -0,0 +1,24 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for getOrderById
+ */
+class GetOrderByIdParameterData
+{
+    /**
+     * ID of pet that needs to be fetched
+     * @DTA\Data(subset="path", field="orderId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="GreaterThan", options={"min":1, "inclusive":true})
+     * @DTA\Validator(subset="path", name="LessThan", options={"max":5, "inclusive":true})
+     * @var int|null
+     */
+    public $order_id;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/GetPetByIdParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/GetPetByIdParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..0ca9dddc1b5403696cc915cb8994d106ecbae0d9
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/GetPetByIdParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for getPetById
+ */
+class GetPetByIdParameterData
+{
+    /**
+     * ID of pet to return
+     * @DTA\Data(subset="path", field="petId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $pet_id;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/GetUserByNameParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/GetUserByNameParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..e215d6d90c64d03904c952f92db1774da58c42d3
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/GetUserByNameParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for getUserByName
+ */
+class GetUserByNameParameterData
+{
+    /**
+     * The name that needs to be fetched. Use user1 for testing.
+     * @DTA\Data(subset="path", field="username")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $username;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/InlineObject.php b/samples/client/petstore/php-dt/src/App/DTO/InlineObject.php
new file mode 100644
index 0000000000000000000000000000000000000000..a5b57634185e6199b7986ad0db90134a83ffa31d
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/InlineObject.php
@@ -0,0 +1,28 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ */
+class InlineObject
+{
+    /**
+     * Updated name of the pet
+     * @DTA\Data(field="name", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $name;
+
+    /**
+     * Updated status of the pet
+     * @DTA\Data(field="status", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $status;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/InlineObject1.php b/samples/client/petstore/php-dt/src/App/DTO/InlineObject1.php
new file mode 100644
index 0000000000000000000000000000000000000000..611b567c40dae96173682564e8c004265dbc7c83
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/InlineObject1.php
@@ -0,0 +1,29 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ */
+class InlineObject1
+{
+    /**
+     * Additional data to pass to server
+     * @DTA\Data(field="additionalMetadata", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $additional_metadata;
+
+    /**
+     * file to upload
+     * @DTA\Data(field="file", nullable=true)
+     * @DTA\Strategy(name="Object", options={"type":\SplFileObject::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":\SplFileObject::class})
+     * @var \SplFileObject|null
+     */
+    public $file;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/LoginUserParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/LoginUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..3c5bcc3b8df2b986048aabb90189af22e5e937e2
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/LoginUserParameterData.php
@@ -0,0 +1,32 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for loginUser
+ */
+class LoginUserParameterData
+{
+    /**
+     * The password for login in clear text
+     * @DTA\Data(subset="query", field="password")
+     * @DTA\Strategy(subset="query", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="query", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $password;
+
+    /**
+     * The user name for login
+     * @DTA\Data(subset="query", field="username")
+     * @DTA\Strategy(subset="query", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="query", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="query", name="Regex", options={"pattern":"/^[a-zA-Z0-9]+[a-zA-Z0-9\\.\\-_]*[a-zA-Z0-9]+$/"})
+     * @var string|null
+     */
+    public $username;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Order.php b/samples/client/petstore/php-dt/src/App/DTO/Order.php
new file mode 100644
index 0000000000000000000000000000000000000000..835bebf66721cab5b844febd8fad7786222ba6fe
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Order.php
@@ -0,0 +1,57 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * An order for a pets from the pet store
+ */
+class Order
+{
+    /**
+     * @DTA\Data(field="id", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $id;
+
+    /**
+     * @DTA\Data(field="petId", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $pet_id;
+
+    /**
+     * @DTA\Data(field="quantity", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $quantity;
+
+    /**
+     * @DTA\Data(field="shipDate", nullable=true)
+     * @DTA\Strategy(name="DateTime")
+     * @DTA\Validator(name="Date", options={"format": \DateTime::RFC3339})
+     * @var \DateTime|null
+     */
+    public $ship_date;
+
+    /**
+     * Order Status
+     * @DTA\Data(field="status", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $status;
+
+    /**
+     * @DTA\Data(field="complete", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"bool"})
+     * @var bool|null
+     */
+    public $complete;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Pet.php b/samples/client/petstore/php-dt/src/App/DTO/Pet.php
new file mode 100644
index 0000000000000000000000000000000000000000..93d887e38d89ec01e1aba7442c7a589bd9d48072
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Pet.php
@@ -0,0 +1,59 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * A pet for sale in the pet store
+ */
+class Pet
+{
+    /**
+     * @DTA\Data(field="id", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $id;
+
+    /**
+     * @DTA\Data(field="category", nullable=true)
+     * @DTA\Strategy(name="Object", options={"type":\App\DTO\Category::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":\App\DTO\Category::class})
+     * @var \App\DTO\Category|null
+     */
+    public $category;
+
+    /**
+     * @DTA\Data(field="name")
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $name;
+
+    /**
+     * @DTA\Data(field="photoUrls")
+     * @DTA\Strategy(name="Object", options={"type":\App\DTO\Collection32::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":\App\DTO\Collection32::class})
+     * @var \App\DTO\Collection32|null
+     */
+    public $photo_urls;
+
+    /**
+     * @DTA\Data(field="tags", nullable=true)
+     * @DTA\Strategy(name="Object", options={"type":\App\DTO\Collection33::class})
+     * @DTA\Validator(name="TypeCompliant", options={"type":\App\DTO\Collection33::class})
+     * @var \App\DTO\Collection33|null
+     */
+    public $tags;
+
+    /**
+     * pet status in the store
+     * @DTA\Data(field="status", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $status;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/Tag.php b/samples/client/petstore/php-dt/src/App/DTO/Tag.php
new file mode 100644
index 0000000000000000000000000000000000000000..ea116dc4d033d5d994cd52913c5b5d72bb69388e
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/Tag.php
@@ -0,0 +1,27 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * A tag for a pet
+ */
+class Tag
+{
+    /**
+     * @DTA\Data(field="id", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $id;
+
+    /**
+     * @DTA\Data(field="name", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $name;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/UpdatePetWithFormParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/UpdatePetWithFormParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..7efcae9913e1f82fad0e9335d4e35fb7f4e23118
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/UpdatePetWithFormParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for updatePetWithForm
+ */
+class UpdatePetWithFormParameterData
+{
+    /**
+     * ID of pet that needs to be updated
+     * @DTA\Data(subset="path", field="petId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $pet_id;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/UpdateUserParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/UpdateUserParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..795f2129f9d92ccfaa60fb7fcd087027c7eeef95
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/UpdateUserParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for updateUser
+ */
+class UpdateUserParameterData
+{
+    /**
+     * name that need to be deleted
+     * @DTA\Data(subset="path", field="username")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $username;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/UploadFileParameterData.php b/samples/client/petstore/php-dt/src/App/DTO/UploadFileParameterData.php
new file mode 100644
index 0000000000000000000000000000000000000000..b915f6911b9fe202219459193c009d52fea3cc31
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/UploadFileParameterData.php
@@ -0,0 +1,22 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * Parameters for uploadFile
+ */
+class UploadFileParameterData
+{
+    /**
+     * ID of pet to update
+     * @DTA\Data(subset="path", field="petId")
+     * @DTA\Strategy(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @DTA\Validator(subset="path", name="QueryStringScalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $pet_id;
+
+}
diff --git a/samples/client/petstore/php-dt/src/App/DTO/User.php b/samples/client/petstore/php-dt/src/App/DTO/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..957c85534786d454ca66ae20b8ac478a589711f5
--- /dev/null
+++ b/samples/client/petstore/php-dt/src/App/DTO/User.php
@@ -0,0 +1,70 @@
+<?php
+declare(strict_types=1);
+
+namespace App\DTO;
+
+use Articus\DataTransfer\Annotation as DTA;
+
+/**
+ * A User who is purchasing from the pet store
+ */
+class User
+{
+    /**
+     * @DTA\Data(field="id", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $id;
+
+    /**
+     * @DTA\Data(field="username", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $username;
+
+    /**
+     * @DTA\Data(field="firstName", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $first_name;
+
+    /**
+     * @DTA\Data(field="lastName", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $last_name;
+
+    /**
+     * @DTA\Data(field="email", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $email;
+
+    /**
+     * @DTA\Data(field="password", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $password;
+
+    /**
+     * @DTA\Data(field="phone", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"string"})
+     * @var string|null
+     */
+    public $phone;
+
+    /**
+     * User Status
+     * @DTA\Data(field="userStatus", nullable=true)
+     * @DTA\Validator(name="Scalar", options={"type":"int"})
+     * @var int|null
+     */
+    public $user_status;
+
+}
diff --git a/website/i18n/en.json b/website/i18n/en.json
index 251a4c177af61f00dee9fded7ce6d46612f1c453..5011d1b3c55498e10a869e9c49e580bbc57c7521 100644
--- a/website/i18n/en.json
+++ b/website/i18n/en.json
@@ -399,6 +399,10 @@
         "title": "Config Options for php-mezzio-ph",
         "sidebar_label": "php-mezzio-ph"
       },
+      "generators/php-dt": {
+        "title": "Config Options for php-dt",
+        "sidebar_label": "php-dt"
+      },
       "generators/php": {
         "title": "Config Options for php",
         "sidebar_label": "php"