From 3d675861090c5f2107c89883c2517b7aae493043 Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Fri, 6 Mar 2020 17:17:57 +0000
Subject: [PATCH 1/6] [kotlin] fix file upload

---
 .../src/main/resources/kotlin-client/api.mustache         | 4 ++--
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 .../main/kotlin/org/openapitools/client/apis/PetApi.kt    | 8 ++++----
 11 files changed, 42 insertions(+), 42 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache
index 20070e1b86b..485b0bed9b5 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/api.mustache
@@ -32,7 +32,7 @@ import {{packageName}}.infrastructure.toMultiValue
     @Suppress("UNCHECKED_CAST"){{/returnType}}
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun {{operationId}}({{#allParams}}{{{paramName}}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) : {{#returnType}}{{{returnType}}}{{#nullableReturnType}}?{{/nullableReturnType}}{{/returnType}}{{^returnType}}Unit{{/returnType}} {
-        val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{{paramName}}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to "${{{paramName}}}"{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}}
+        val localVariableBody: kotlin.Any? = {{#hasBodyParam}}{{#bodyParams}}{{{paramName}}}{{/bodyParams}}{{/hasBodyParam}}{{^hasBodyParam}}{{^hasFormParams}}null{{/hasFormParams}}{{#hasFormParams}}mapOf({{#formParams}}"{{{baseName}}}" to {{{paramName}}}{{#hasMore}}, {{/hasMore}}{{/formParams}}){{/hasFormParams}}{{/hasBodyParam}}
         val localVariableQuery: MultiValueMap = {{^hasQueryParams}}mutableMapOf()
 {{/hasQueryParams}}{{#hasQueryParams}}mutableMapOf<kotlin.String, List<kotlin.String>>()
             .apply {
@@ -55,7 +55,7 @@ import {{packageName}}.infrastructure.toMultiValue
                 {{/queryParams}}
             }
             {{/hasQueryParams}}
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf({{#hasFormParams}}"Content-Type" to {{^consumes}}"multipart/form-data"{{/consumes}}{{#consumes.0}}"{{MediaType}}"{{/consumes.0}}{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{baseName}}" to {{#isContainer}}{{{paramName}}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{{paramName}}}.toString(){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}}
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf({{#hasFormParams}}"Content-Type" to {{^consumes}}"multipart/form-data"{{/consumes}}{{#consumes.0}}"{{{mediaType}}}"{{/consumes.0}}{{/hasFormParams}}{{^hasHeaderParams}}){{/hasHeaderParams}}{{#hasHeaderParams}}{{#hasFormParams}}, {{/hasFormParams}}{{#headerParams}}"{{baseName}}" to {{#isContainer}}{{{paramName}}}.joinToString(separator = collectionDelimiter("{{collectionFormat}}")){{/isContainer}}{{^isContainer}}{{{paramName}}}.toString(){{/isContainer}}{{#hasMore}}, {{/hasMore}}{{/headerParams}}){{/hasHeaderParams}}
         val localVariableConfig = RequestConfig(
             RequestMethod.{{httpMethod}},
             "{{path}}"{{#pathParams}}.replace("{"+"{{baseName}}"+"}", "${{{paramName}}}"){{/pathParams}},
diff --git a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 97248ed4cfd..d5906cbd656 100644
--- a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -293,9 +293,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -336,9 +336,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 51247617d9c..50770e4c745 100644
--- a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ internal class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2")
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ internal class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2")
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index de4ab6dbb83..cf797f67c9f 100644
--- a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse? {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 69d1e725e49..93269dced25 100644
--- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
index 2e3b24ae2ea..a2698dc47ea 100644
--- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
+++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/apis/PetApi.kt
@@ -291,9 +291,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     */
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun updatePetWithForm(petId: kotlin.Long, name: kotlin.String?, status: kotlin.String?) : Unit {
-        val localVariableBody: kotlin.Any? = mapOf("name" to "$name", "status" to "$status")
+        val localVariableBody: kotlin.Any? = mapOf("name" to name, "status" to status)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "application/x-www-form-urlencoded")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}".replace("{"+"petId"+"}", "$petId"),
@@ -334,9 +334,9 @@ class PetApi(basePath: kotlin.String = "http://petstore.swagger.io/v2") : ApiCli
     @Suppress("UNCHECKED_CAST")
     @Throws(UnsupportedOperationException::class, ClientException::class, ServerException::class)
     fun uploadFile(petId: kotlin.Long, additionalMetadata: kotlin.String?, file: java.io.File?) : ApiResponse {
-        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to "$additionalMetadata", "file" to "$file")
+        val localVariableBody: kotlin.Any? = mapOf("additionalMetadata" to additionalMetadata, "file" to file)
         val localVariableQuery: MultiValueMap = mutableMapOf()
-        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "")
+        val localVariableHeaders: MutableMap<String, String> = mutableMapOf("Content-Type" to "multipart/form-data")
         val localVariableConfig = RequestConfig(
             RequestMethod.POST,
             "/pet/{petId}/uploadImage".replace("{"+"petId"+"}", "$petId"),
-- 
GitLab


From c69407942bebd2138be27e2b10b3d0530e26f99a Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Fri, 6 Mar 2020 17:28:53 +0000
Subject: [PATCH 2/6] [kotlin] fix file upload

---
 .../kotlin-client/data_class.mustache         |  3 +-
 .../infrastructure/ApiClient.kt.mustache      | 86 ++++++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 81 ++++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 .../client/infrastructure/ApiClient.kt        | 72 +++++++++++++++-
 12 files changed, 792 insertions(+), 26 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
index 7ec7de32c8b..cb155744eb0 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
@@ -36,8 +36,7 @@ import java.io.Serializable
 {{/parcelizeModels}}
 {{#multiplatform}}@Serializable{{/multiplatform}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}
 {{#nonPublicApi}}internal {{/nonPublicApi}}{{#discriminator}}interface{{/discriminator}}{{^discriminator}}data class{{/discriminator}} {{classname}}{{^discriminator}} (
-{{#vars}}
-{{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}}
+{{#vars}}{{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}}
 {{/vars}}
 ){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{parent}}{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{parent}}, Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{parent}}, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{parent}}, Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#vendorExtensions.x-has-data-class-body}} {
 {{/vendorExtensions.x-has-data-class-body}}
diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
index 8913d9e5ae3..6794b3ed1ce 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
@@ -22,7 +22,25 @@ import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 {{/jvm-okhttp4}}
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+{{^threetenbp}}
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
+{{/threetenbp}}
+{{#threetenbp}}
+import org.threeten.bp.LocalDate
+import org.threeten.bp.LocalDateTime
+import org.threeten.bp.LocalTime
+import org.threeten.bp.OffsetDateTime
+import org.threeten.bp.OffsetTime
+{{/threetenbp}}
 
 {{#nonPublicApi}}internal {{/nonPublicApi}}open class ApiClient(val baseUrl: String) {
     {{#nonPublicApi}}internal {{/nonPublicApi}}companion object {
@@ -49,6 +67,17 @@ import java.io.File
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             {{#jvm-okhttp3}}
@@ -61,9 +90,37 @@ import java.io.File
                 mediaType.toMediaTypeOrNull()
             )
             {{/jvm-okhttp4}}
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -254,7 +311,26 @@ import java.io.File
         }
     }
 
-    {{^jackson}}
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         {{#toJson}}
         /*
@@ -269,10 +345,12 @@ import java.io.File
         {{#gson}}
         return Serializer.gson.toJson(value, T::class.java).replace("\"", "")
         {{/gson}}
+        {{#jackson}}
+        return Serializer.jackson.toJson(value, T::class.java).replace("\"", "")
+        {{/jackson}}
         {{/toJson}}
         {{^toJson}}
         return value.toString()
         {{/toJson}}
     }
-    {{/jackson}}
 }
diff --git a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 7876fe75504..262f660c003 100644
--- a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 3047834f4ef..3a4632f14b4 100644
--- a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,4 +220,33 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
+    protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
+        /*
+        .replace("\"", "") converts the json object string to an actual string for the query parameter.
+        The moshi or gson adapter allows a more generic solution instead of trying to use a native
+        formatter. It also easily allows to provide a simple way to define a custom date format pattern
+        inside a gson/moshi adapter.
+        */
+        return Serializer.jackson.toJson(value, T::class.java).replace("\"", "")
+    }
 }
diff --git a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index feb9aeebbf6..94cb8a284e7 100644
--- a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         return value.toString()
     }
diff --git a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 5d3ecd7b31f..c8b557ca182 100644
--- a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c591f98d389..c642096927e 100644
--- a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 internal open class ApiClient(val baseUrl: String) {
     internal companion object {
@@ -37,14 +46,53 @@ internal open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ internal open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 5d3ecd7b31f..c8b557ca182 100644
--- a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 1588da740d4..9e3b1e8cbee 100644
--- a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -8,7 +8,16 @@ import okhttp3.FormBody
 import okhttp3.HttpUrl
 import okhttp3.ResponseBody
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -35,14 +44,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> RequestBody.create(
                 MediaType.parse(mediaType), content
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -170,6 +218,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 5d3ecd7b31f..c8b557ca182 100644
--- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 5d3ecd7b31f..2e03bce62c7 100644
--- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import org.threeten.bp.LocalDate
+import org.threeten.bp.LocalDateTime
+import org.threeten.bp.LocalTime
+import org.threeten.bp.OffsetDateTime
+import org.threeten.bp.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 5d3ecd7b31f..c8b557ca182 100644
--- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -10,7 +10,16 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
 import okhttp3.ResponseBody
 import okhttp3.MediaType.Companion.toMediaTypeOrNull
 import okhttp3.Request
+import okhttp3.Headers
+import okhttp3.MultipartBody
 import java.io.File
+import java.net.URLConnection
+import java.util.Date
+import java.time.LocalDate
+import java.time.LocalDateTime
+import java.time.LocalTime
+import java.time.OffsetDateTime
+import java.time.OffsetTime
 
 open class ApiClient(val baseUrl: String) {
     companion object {
@@ -37,14 +46,53 @@ open class ApiClient(val baseUrl: String) {
         val builder: OkHttpClient.Builder = OkHttpClient.Builder()
     }
 
+    /**
+     * Guess Content-Type header from the given file (defaults to "application/octet-stream").
+     *
+     * @param file The given file
+     * @return The guessed Content-Type
+     */
+    protected fun guessContentTypeFromFile(file: File): String {
+        val contentType = URLConnection.guessContentTypeFromName(file.name)
+        return contentType ?: "application/octet-stream"
+    }
+
     protected inline fun <reified T> requestBody(content: T, mediaType: String = JsonMediaType): RequestBody =
         when {
             content is File -> content.asRequestBody(
                 mediaType.toMediaTypeOrNull()
             )
-            mediaType == FormDataMediaType || mediaType == FormUrlEncMediaType -> {
+            mediaType == FormDataMediaType -> {
+                MultipartBody.Builder()
+                    .setType(MultipartBody.FORM)
+                    .apply {
+                        // content's type *must* be Map<String, Any?>
+                        @Suppress("UNCHECKED_CAST")
+                        (content as Map<String, Any?>).forEach { (key, value) ->
+                            if (value is File) {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\"; filename=\"${value.name}\""
+                                )
+                                val fileMediaType = guessContentTypeFromFile(value)
+                                    .toMediaTypeOrNull()
+                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                            } else {
+                                val partHeaders = Headers.headersOf(
+                                    "Content-Disposition",
+                                    "form-data; name=\"$key\""
+                                )
+                                addPart(
+                                    partHeaders,
+                                    parameterToString(value).toRequestBody(null)
+                                )
+                            }
+                        }
+                    }.build()
+            }
+            mediaType == FormUrlEncMediaType -> {
                 FormBody.Builder().apply {
-                    // content's type *must* be Map<String, Any>
+                    // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
                     (content as Map<String,String>).forEach { (key, value) ->
                         add(key, value)
@@ -172,6 +220,26 @@ open class ApiClient(val baseUrl: String) {
         }
     }
 
+    protected fun parameterToString(value: Any?): String {
+        when (value) {
+            null -> {
+                return ""
+            }
+            is Array<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is Iterable<*> -> {
+                return toMultiValue(value, "csv").toString()
+            }
+            is OffsetDateTime, is OffsetTime, is LocalDateTime, is LocalDate, is LocalTime, is Date -> {
+                return parseDateToQueryString<Any>(value)
+            }
+            else -> {
+                return value.toString()
+            }
+        }
+    }
+
     protected inline fun <reified T: Any> parseDateToQueryString(value : T): String {
         /*
         .replace("\"", "") converts the json object string to an actual string for the query parameter.
-- 
GitLab


From 43c2c27c5fc493d59648699f36b1717be68a866c Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Fri, 6 Mar 2020 17:39:12 +0000
Subject: [PATCH 3/6] [kotlin] fix file upload

---
 .../src/main/resources/kotlin-client/data_class.mustache       | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
index cb155744eb0..7ec7de32c8b 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/data_class.mustache
@@ -36,7 +36,8 @@ import java.io.Serializable
 {{/parcelizeModels}}
 {{#multiplatform}}@Serializable{{/multiplatform}}{{#moshi}}{{#moshiCodeGen}}@JsonClass(generateAdapter = true){{/moshiCodeGen}}{{/moshi}}
 {{#nonPublicApi}}internal {{/nonPublicApi}}{{#discriminator}}interface{{/discriminator}}{{^discriminator}}data class{{/discriminator}} {{classname}}{{^discriminator}} (
-{{#vars}}{{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}}
+{{#vars}}
+{{#required}}{{>data_class_req_var}}{{/required}}{{^required}}{{>data_class_opt_var}}{{/required}}{{^-last}},{{/-last}}
 {{/vars}}
 ){{/discriminator}}{{#parent}}{{^serializableModel}}{{^parcelizeModels}} : {{parent}}{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{^parcelizeModels}} : {{parent}}, Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{^serializableModel}}{{#parcelizeModels}} : {{parent}}, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#parent}}{{#serializableModel}}{{#parcelizeModels}} : {{parent}}, Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{^parcelizeModels}} : Serializable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{^serializableModel}}{{#parcelizeModels}} : Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{^parent}}{{#serializableModel}}{{#parcelizeModels}} : Serializable, Parcelable{{/parcelizeModels}}{{/serializableModel}}{{/parent}}{{#vendorExtensions.x-has-data-class-body}} {
 {{/vendorExtensions.x-has-data-class-body}}
-- 
GitLab


From 50c857cbfbafd56921c0679e8438cd2cf4e72cf6 Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Sun, 8 Mar 2020 21:34:10 +0000
Subject: [PATCH 4/6] [kotlin][client] fix jackson integration

---
 .../libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache | 4 ++--
 .../org/openapitools/client/infrastructure/ApiClient.kt       | 2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
index 6794b3ed1ce..7e4f4c9302b 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
@@ -136,7 +136,7 @@ import org.threeten.bp.OffsetTime
                 MediaType.parse(mediaType), Serializer.gson.toJson(content, T::class.java)
                 {{/gson}}
                 {{#jackson}}
-                MediaType.parse(mediaType), Serializer.jackson.toJson(content, T::class.java)
+                MediaType.parse(mediaType), Serializer.jacksonObjectMapper.writeValueAsString(content)
                 {{/jackson}}
             )
             {{/jvm-okhttp3}}
@@ -346,7 +346,7 @@ import org.threeten.bp.OffsetTime
         return Serializer.gson.toJson(value, T::class.java).replace("\"", "")
         {{/gson}}
         {{#jackson}}
-        return Serializer.jackson.toJson(value, T::class.java).replace("\"", "")
+        return Serializer.jacksonObjectMapper.writeValueAsString(value).replace("\"", "")
         {{/jackson}}
         {{/toJson}}
         {{^toJson}}
diff --git a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 3a4632f14b4..a98522d7166 100644
--- a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -247,6 +247,6 @@ open class ApiClient(val baseUrl: String) {
         formatter. It also easily allows to provide a simple way to define a custom date format pattern
         inside a gson/moshi adapter.
         */
-        return Serializer.jackson.toJson(value, T::class.java).replace("\"", "")
+        return Serializer.jacksonObjectMapper.writeValueAsString(value).replace("\"", "")
     }
 }
-- 
GitLab


From d31cd59a54c8931e1ce70cc87f9c15b729691d51 Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Sun, 8 Mar 2020 22:31:51 +0000
Subject: [PATCH 5/6] [kotlin] fix file upload

---
 .../infrastructure/ApiClient.kt.mustache      | 22 ++++++++++++++-----
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        | 15 ++++++-------
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 .../client/infrastructure/ApiClient.kt        |  7 +++---
 11 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
index 7e4f4c9302b..575d743d870 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
@@ -98,21 +98,31 @@ import org.threeten.bp.OffsetTime
                         @Suppress("UNCHECKED_CAST")
                         (content as Map<String, Any?>).forEach { (key, value) ->
                             if (value is File) {
-                                val partHeaders = Headers.headersOf(
+                                val partHeaders = Headers.{{#jvm-okhttp3}}of{{/jvm-okhttp3}}{{#jvm-okhttp4}}headersOf{{/jvm-okhttp4}}(
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                {{#jvm-okhttp3}}
+                                val fileMediaType = MediaType.parse(guessContentTypeFromFile(value))
+                                addPart(partHeaders, RequestBody.create(fileMediaType, value)
+                                {{/jvm-okhttp3}}
+                                {{#jvm-okhttp4}}
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
+                                {{/jvm-okhttp4}}
                             } else {
-                                val partHeaders = Headers.headersOf(
+                                val partHeaders = Headers.{{#jvm-okhttp3}}of{{/jvm-okhttp3}}{{#jvm-okhttp4}}headersOf{{/jvm-okhttp4}}(
                                     "Content-Disposition",
                                     "form-data; name=\"$key\""
                                 )
                                 addPart(
                                     partHeaders,
+                                    {{#jvm-okhttp3}}
+                                    RequestBody.create(null, parameterToString(value))
+                                    {{/jvm-okhttp3}}
+                                    {{#jvm-okhttp4}}
                                     parameterToString(value).toRequestBody(null)
+                                    {{/jvm-okhttp4}}
                                 )
                             }
                         }
@@ -122,8 +132,8 @@ import org.threeten.bp.OffsetTime
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 262f660c003..5d64a9add42 100644
--- a/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-gson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index a98522d7166..2c15d73b189 100644
--- a/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-jackson/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 94cb8a284e7..a69de1961da 100644
--- a/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-json-request-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c8b557ca182..e7f366d02cd 100644
--- a/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-moshi-codegen/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c642096927e..473b3fd42ce 100644
--- a/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-nonpublic/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ internal open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ internal open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c8b557ca182..e7f366d02cd 100644
--- a/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-nullable/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 9e3b1e8cbee..941a2b17f47 100644
--- a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -68,21 +68,20 @@ open class ApiClient(val baseUrl: String) {
                         @Suppress("UNCHECKED_CAST")
                         (content as Map<String, Any?>).forEach { (key, value) ->
                             if (value is File) {
-                                val partHeaders = Headers.headersOf(
+                                val partHeaders = Headers.of(
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
-                                addPart(partHeaders, value.asRequestBody(fileMediaType))
+                                val fileMediaType = MediaType.parse(guessContentTypeFromFile(value))
+                                addPart(partHeaders, RequestBody.create(fileMediaType, value)
                             } else {
-                                val partHeaders = Headers.headersOf(
+                                val partHeaders = Headers.of(
                                     "Content-Disposition",
                                     "form-data; name=\"$key\""
                                 )
                                 addPart(
                                     partHeaders,
-                                    parameterToString(value).toRequestBody(null)
+                                    RequestBody.create(null, parameterToString(value))
                                 )
                             }
                         }
@@ -92,8 +91,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c8b557ca182..e7f366d02cd 100644
--- a/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-string/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 2e03bce62c7..cb540f6ebd7 100644
--- a/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-threetenbp/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
diff --git a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index c8b557ca182..e7f366d02cd 100644
--- a/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -74,8 +74,7 @@ open class ApiClient(val baseUrl: String) {
                                     "Content-Disposition",
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
-                                val fileMediaType = guessContentTypeFromFile(value)
-                                    .toMediaTypeOrNull()
+                                val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
                                 addPart(partHeaders, value.asRequestBody(fileMediaType))
                             } else {
                                 val partHeaders = Headers.headersOf(
@@ -94,8 +93,8 @@ open class ApiClient(val baseUrl: String) {
                 FormBody.Builder().apply {
                     // content's type *must* be Map<String, Any?>
                     @Suppress("UNCHECKED_CAST")
-                    (content as Map<String,String>).forEach { (key, value) ->
-                        add(key, value)
+                    (content as Map<String, Any?>).forEach { (key, value) ->
+                        add(key, parameterToString(value))
                     }
                 }.build()
             }
-- 
GitLab


From c03e3115d88cb4141f13168b3dc8617c28aff481 Mon Sep 17 00:00:00 2001
From: Bruno Coelho <4brunu@gmail.com>
Date: Mon, 9 Mar 2020 08:24:32 +0000
Subject: [PATCH 6/6] [kotlin] fix file upload

---
 .../libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache   | 2 +-
 .../kotlin/org/openapitools/client/infrastructure/ApiClient.kt  | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
index 575d743d870..3bff3d10d97 100644
--- a/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
+++ b/modules/openapi-generator/src/main/resources/kotlin-client/libraries/jvm-okhttp/infrastructure/ApiClient.kt.mustache
@@ -104,7 +104,7 @@ import org.threeten.bp.OffsetTime
                                 )
                                 {{#jvm-okhttp3}}
                                 val fileMediaType = MediaType.parse(guessContentTypeFromFile(value))
-                                addPart(partHeaders, RequestBody.create(fileMediaType, value)
+                                addPart(partHeaders, RequestBody.create(fileMediaType, value))
                                 {{/jvm-okhttp3}}
                                 {{#jvm-okhttp4}}
                                 val fileMediaType = guessContentTypeFromFile(value).toMediaTypeOrNull()
diff --git a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
index 941a2b17f47..f60e40309bc 100644
--- a/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
+++ b/samples/client/petstore/kotlin-okhttp3/src/main/kotlin/org/openapitools/client/infrastructure/ApiClient.kt
@@ -73,7 +73,7 @@ open class ApiClient(val baseUrl: String) {
                                     "form-data; name=\"$key\"; filename=\"${value.name}\""
                                 )
                                 val fileMediaType = MediaType.parse(guessContentTypeFromFile(value))
-                                addPart(partHeaders, RequestBody.create(fileMediaType, value)
+                                addPart(partHeaders, RequestBody.create(fileMediaType, value))
                             } else {
                                 val partHeaders = Headers.of(
                                     "Content-Disposition",
-- 
GitLab