From d2ea1d9634a132d92fe5837a279192125f58a674 Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Fri, 17 Aug 2018 16:25:29 +0800
Subject: [PATCH 01/16] Add an option for Dart2

---
 .../codegen/languages/DartClientCodegen.java  |   8 +-
 .../src/main/resources/dart2/README.mustache  | 133 ++++++++++++++
 .../src/main/resources/dart2/api.mustache     | 117 +++++++++++++
 .../main/resources/dart2/api_client.mustache  | 164 ++++++++++++++++++
 .../src/main/resources/dart2/api_doc.mustache |  86 +++++++++
 .../resources/dart2/api_exception.mustache    |  23 +++
 .../main/resources/dart2/api_helper.mustache  |  52 ++++++
 .../src/main/resources/dart2/apilib.mustache  |  21 +++
 .../dart2/auth/api_key_auth.mustache          |  27 +++
 .../dart2/auth/authentication.mustache        |   7 +
 .../dart2/auth/http_basic_auth.mustache       |  14 ++
 .../main/resources/dart2/auth/oauth.mustache  |  18 ++
 .../src/main/resources/dart2/class.mustache   |  82 +++++++++
 .../src/main/resources/dart2/enum.mustache    |  36 ++++
 .../main/resources/dart2/git_push.sh.mustache |  52 ++++++
 .../main/resources/dart2/gitignore.mustache   |  27 +++
 .../src/main/resources/dart2/model.mustache   |  12 ++
 .../main/resources/dart2/object_doc.mustache  |  16 ++
 .../src/main/resources/dart2/pubspec.mustache |   5 +
 .../options/DartClientOptionsProvider.java    |   1 +
 20 files changed, 900 insertions(+), 1 deletion(-)
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/README.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/api.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/api_client.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/api_exception.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/api_helper.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/apilib.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/class.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/enum.mustache
 create mode 100755 modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/gitignore.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/model.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/object_doc.mustache
 create mode 100644 modules/openapi-generator/src/main/resources/dart2/pubspec.mustache

diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
index 6203fb04980..32a6338a10f 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
@@ -47,6 +47,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
     public static final String PUB_VERSION = "pubVersion";
     public static final String PUB_DESCRIPTION = "pubDescription";
     public static final String USE_ENUM_EXTENSION = "useEnumExtension";
+    public static final String SUPPORT_DART2 = "supportDart2";
     protected boolean browserClient = true;
     protected String pubName = "openapi";
     protected String pubVersion = "1.0.0";
@@ -124,6 +125,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
         cliOptions.add(new CliOption(PUB_DESCRIPTION, "Description in generated pubspec"));
         cliOptions.add(new CliOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums"));
         cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code"));
+        cliOptions.add(new CliOption(SUPPORT_DART2, "support dart2").defaultValue("false"));
     }
 
     @Override
@@ -188,9 +190,13 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
         additionalProperties.put("apiDocPath", apiDocPath);
         additionalProperties.put("modelDocPath", modelDocPath);
 
+        if (Boolean.TRUE.equals(additionalProperties.get(SUPPORT_DART2))) {
+            embeddedTemplateDir = templateDir = "dart2";
+        } else {
+            supportingFiles.add(new SupportingFile("analysis_options.mustache", "", ".analysis_options"));
+        }
         final String libFolder = sourceFolder + File.separator + "lib";
         supportingFiles.add(new SupportingFile("pubspec.mustache", "", "pubspec.yaml"));
-        supportingFiles.add(new SupportingFile("analysis_options.mustache", "", ".analysis_options"));
         supportingFiles.add(new SupportingFile("api_client.mustache", libFolder, "api_client.dart"));
         supportingFiles.add(new SupportingFile("api_exception.mustache", libFolder, "api_exception.dart"));
         supportingFiles.add(new SupportingFile("api_helper.mustache", libFolder, "api_helper.dart"));
diff --git a/modules/openapi-generator/src/main/resources/dart2/README.mustache b/modules/openapi-generator/src/main/resources/dart2/README.mustache
new file mode 100644
index 00000000000..1766ea72105
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/README.mustache
@@ -0,0 +1,133 @@
+# {{pubName}}
+{{#appDescription}}
+{{{appDescription}}}
+{{/appDescription}}
+
+This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: {{appVersion}}
+{{#artifactVersion}}
+- Package version: {{artifactVersion}}
+{{/artifactVersion}}
+{{^hideGenerationTimestamp}}
+- Build date: {{generatedDate}}
+{{/hideGenerationTimestamp}}
+- Build package: {{generatorClass}}
+{{#infoUrl}}
+For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
+{{/infoUrl}}
+
+## Requirements
+
+Dart 1.20.0 or later OR Flutter 0.0.20 or later
+
+## Installation & Usage
+
+### Github
+If this Dart package is published to Github, please include the following in pubspec.yaml
+```
+name: {{pubName}}
+version: {{pubVersion}}
+description: {{pubDescription}}
+dependencies:
+  {{pubName}}:
+    git: https://github.com/{{gitUserId}}/{{gitRepoId}}.git
+      version: 'any'
+```
+
+### Local
+To use the package in your local drive, please include the following in pubspec.yaml
+```
+dependencies:
+  {{pubName}}:
+    path: /path/to/{{pubName}}
+```
+
+## Tests
+
+TODO
+
+## Getting Started
+
+Please follow the [installation procedure](#installation--usage) and then run the following:
+
+```dart
+import 'package:{{pubName}}/api.dart';
+{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}
+{{#hasAuthMethods}}
+{{#authMethods}}
+{{#isBasic}}
+// TODO Configure HTTP basic authorization: {{{name}}}
+//{{pubName}}.api.Configuration.username = 'YOUR_USERNAME';
+//{{pubName}}.api.Configuration.password = 'YOUR_PASSWORD';
+{{/isBasic}}
+{{#isApiKey}}
+// TODO Configure API key authorization: {{{name}}}
+//{{pubName}}.api.Configuration.apiKey{'{{{keyParamName}}}'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//{{pubName}}.api.Configuration.apiKeyPrefix{'{{{keyParamName}}}'} = "Bearer";
+{{/isApiKey}}
+{{#isOAuth}}
+// TODO Configure OAuth2 access token for authorization: {{{name}}}
+//{{pubName}}.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+{{/isOAuth}}
+{{/authMethods}}
+{{/hasAuthMethods}}
+
+var api_instance = new {{classname}}();
+{{#allParams}}
+var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}new {{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
+{{/allParams}}
+
+try {
+    {{#returnType}}var result = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+    {{#returnType}}
+    print(result);
+    {{/returnType}}
+} catch (e) {
+    print("Exception when calling {{classname}}->{{operationId}}: $e\n");
+}
+{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *{{basePath}}*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}/{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
+{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
+
+## Documentation For Models
+
+{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}/{{{classname}}}.md)
+{{/model}}{{/models}}
+
+## Documentation For Authorization
+
+{{^authMethods}} All endpoints do not require authorization.
+{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
+{{#authMethods}}## {{{name}}}
+
+{{#isApiKey}}- **Type**: API key
+- **API key parameter name**: {{{keyParamName}}}
+- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
+{{/isApiKey}}
+{{#isBasic}}- **Type**: HTTP basic authentication
+{{/isBasic}}
+{{#isOAuth}}- **Type**: OAuth
+- **Flow**: {{{flow}}}
+- **Authorization URL**: {{{authorizationUrl}}}
+- **Scopes**: {{^scopes}}N/A{{/scopes}}
+{{#scopes}} - **{{{scope}}}**: {{{description}}}
+{{/scopes}}
+{{/isOAuth}}
+
+{{/authMethods}}
+
+## Author
+
+{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
+{{/hasMore}}{{/apis}}{{/apiInfo}}
+
diff --git a/modules/openapi-generator/src/main/resources/dart2/api.mustache b/modules/openapi-generator/src/main/resources/dart2/api.mustache
new file mode 100644
index 00000000000..18a70be92ab
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/api.mustache
@@ -0,0 +1,117 @@
+part of {{pubName}}.api;
+
+{{#operations}}
+
+
+class {{classname}} {
+  final ApiClient apiClient;
+
+  {{classname}}([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  {{#operation}}
+  /// {{summary}}
+  ///
+  /// {{notes}}
+  {{#returnType}}Future<{{{returnType}}}> {{/returnType}}{{^returnType}}Future {{/returnType}}{{nickname}}({{#allParams}}{{#required}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async {
+    Object postBody;
+
+    // verify required params are set
+    {{#allParams}}
+      {{#required}}
+    if({{paramName}} == null) {
+     throw new ApiException(400, "Missing required param: {{paramName}}");
+    }
+      {{/required}}
+    {{/allParams}}
+
+    // create path and map variables
+    String path = "{{{path}}}".replaceAll("{format}","json"){{#pathParams}}.replaceAll("{" + "{{baseName}}" + "}", {{{paramName}}}.toString()){{/pathParams}};
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+    {{#queryParams}}
+    {{^required}}
+    if({{paramName}} != null) {
+    {{/required}}
+      queryParams.addAll(_convertParametersForCollectionFormat("{{collectionFormat}}", "{{baseName}}", {{paramName}}));
+    {{^required}}
+    }
+    {{/required}}
+    {{/queryParams}}
+    {{#headerParams}}
+    headerParams["{{baseName}}"] = {{paramName}};
+    {{/headerParams}}
+
+    List<String> contentTypes = [{{#consumes}}"{{{mediaType}}}"{{#hasMore}},{{/hasMore}}{{/consumes}}];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [{{#authMethods}}"{{name}}"{{#hasMore}}, {{/hasMore}}{{/authMethods}}];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      {{#formParams}}
+      {{^isFile}}
+      if ({{paramName}} != null) {
+        hasFields = true;
+        mp.fields['{{baseName}}'] = parameterToString({{paramName}});
+      }
+      {{/isFile}}
+      {{#isFile}}
+      if ({{paramName}} != null) {
+        hasFields = true;
+        mp.fields['{{baseName}}'] = {{paramName}}.field;
+        mp.files.add({{paramName}});
+      }
+      {{/isFile}}
+      {{/formParams}}
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      {{#formParams}}
+      {{^isFile}}
+      if ({{paramName}} != null)
+        formParams['{{baseName}}'] = parameterToString({{paramName}});
+      {{/isFile}}
+      {{/formParams}}
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             '{{httpMethod}}',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      {{#isListContainer}}
+        {{#returnType}}
+      return (apiClient.deserialize(response.body, '{{{returnType}}}') as List).map((item) => item as {{returnBaseType}}).toList();
+        {{/returnType}}
+      {{/isListContainer}}
+      {{^isListContainer}}
+        {{#isMapContainer}}
+          {{#returnType}}
+      return new {{{returnType}}}.from(apiClient.deserialize(response.body, '{{{returnType}}}'));
+          {{/returnType}};
+        {{/isMapContainer}}
+        {{^isMapContainer}}
+          {{#returnType}}
+      return apiClient.deserialize(response.body, '{{{returnType}}}') as {{{returnType}}};
+          {{/returnType}}
+        {{/isMapContainer}}
+      {{/isListContainer}}
+    } else {
+      return{{#returnType}} null{{/returnType}};
+    }
+  }
+  {{/operation}}
+}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_client.mustache b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache
new file mode 100644
index 00000000000..9b83baf71dd
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/api_client.mustache
@@ -0,0 +1,164 @@
+part of {{pubName}}.api;
+
+class QueryParam {
+  String name;
+  String value;
+
+  QueryParam(this.name, this.value);
+}
+
+class ApiClient {
+
+  String basePath;
+  var client = {{#browserClient}}Browser{{/browserClient}}Client();
+
+  Map<String, String> _defaultHeaderMap = {};
+  Map<String, Authentication> _authentications = {};
+
+  final _regList = RegExp(r'^List<(.*)>$');
+  final _regMap = RegExp(r'^Map<String,(.*)>$');
+
+  ApiClient({this.basePath: "{{{basePath}}}"}) {
+    // Setup authentications (key: authentication name, value: authentication).{{#authMethods}}{{#isBasic}}
+    _authentications['{{name}}'] = HttpBasicAuth();{{/isBasic}}{{#isApiKey}}
+    _authentications['{{name}}'] = ApiKeyAuth({{#isKeyInHeader}}"header"{{/isKeyInHeader}}{{^isKeyInHeader}}"query"{{/isKeyInHeader}}, "{{keyParamName}}");{{/isApiKey}}{{#isOAuth}}
+    _authentications['{{name}}'] = OAuth();{{/isOAuth}}{{/authMethods}}
+  }
+
+  void addDefaultHeader(String key, String value) {
+     _defaultHeaderMap[key] = value;
+  }
+
+  dynamic _deserialize(dynamic value, String targetType) {
+    try {
+      switch (targetType) {
+        case 'String':
+          return '$value';
+        case 'int':
+          return value is int ? value : int.parse('$value');
+        case 'bool':
+          return value is bool ? value : '$value'.toLowerCase() == 'true';
+        case 'double':
+          return value is double ? value : double.parse('$value');
+        {{#models}}
+          {{#model}}
+        case '{{classname}}':
+            {{#isEnum}}
+          // Enclose the value in a list so that Dartson can use a transformer
+          // to decode it.
+          final listValue = [value];
+          final List<dynamic> listResult = dson.map(listValue, []);
+          return listResult[0];
+            {{/isEnum}}
+            {{^isEnum}}
+          return {{classname}}.fromJson(value);
+            {{/isEnum}}
+          {{/model}}
+        {{/models}}
+        default:
+          {
+            Match match;
+            if (value is List &&
+                (match = _regList.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return value.map((v) => _deserialize(v, newTargetType)).toList();
+            } else if (value is Map &&
+                (match = _regMap.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return Map.fromIterables(value.keys,
+                  value.values.map((v) => _deserialize(v, newTargetType)));
+            }
+          }
+      }
+    } catch (e, stack) {
+      throw ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+    }
+    throw ApiException(500, 'Could not find a suitable class for deserialization');
+  }
+
+  dynamic deserialize(String json, String targetType) {
+    // Remove all spaces.  Necessary for reg expressions as well.
+    targetType = targetType.replaceAll(' ', '');
+
+    if (targetType == 'String') return json;
+
+    var decodedJson = jsonDecode(json);
+    return _deserialize(decodedJson, targetType);
+  }
+
+  String serialize(Object obj) {
+    String serialized = '';
+    if (obj == null) {
+      serialized = '';
+    } else {
+      serialized = json.encode(obj);
+    }
+    return serialized;
+  }
+
+  // We don't use a Map<String, String> for queryParams.
+  // If collectionFormat is 'multi' a key might appear multiple times.
+  Future<Response> invokeAPI(String path,
+                             String method,
+                             Iterable<QueryParam> queryParams,
+                             Object body,
+                             Map<String, String> headerParams,
+                             Map<String, String> formParams,
+                             String contentType,
+                             List<String> authNames) async {
+
+    _updateParamsForAuth(authNames, queryParams, headerParams);
+
+    var ps = queryParams.where((p) => p.value != null).map((p) => '${p.name}=${p.value}');
+    String queryString = ps.isNotEmpty ?
+                         '?' + ps.join('&') :
+                         '';
+
+    String url = basePath + path + queryString;
+
+    headerParams.addAll(_defaultHeaderMap);
+    headerParams['Content-Type'] = contentType;
+
+    if(body is MultipartRequest) {
+      var request = MultipartRequest(method, Uri.parse(url));
+      request.fields.addAll(body.fields);
+      request.files.addAll(body.files);
+      request.headers.addAll(body.headers);
+      request.headers.addAll(headerParams);
+      var response = await client.send(request);
+      return Response.fromStream(response);
+    } else {
+      var msgBody = contentType == "application/x-www-form-urlencoded" ? formParams : serialize(body);
+      switch(method) {
+        case "POST":
+          return client.post(url, headers: headerParams, body: msgBody);
+        case "PUT":
+          return client.put(url, headers: headerParams, body: msgBody);
+        case "DELETE":
+          return client.delete(url, headers: headerParams);
+        case "PATCH":
+          return client.patch(url, headers: headerParams, body: msgBody);
+        default:
+          return client.get(url, headers: headerParams);
+      }
+    }
+  }
+
+  /// Update query and header parameters based on authentication settings.
+  /// @param authNames The authentications to apply
+  void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
+    authNames.forEach((authName) {
+      Authentication auth = _authentications[authName];
+      if (auth == null) throw ArgumentError("Authentication undefined: " + authName);
+      auth.applyToParams(queryParams, headerParams);
+    });
+  }
+
+  void setAccessToken(String accessToken) {
+    _authentications.forEach((key, auth) {
+      if (auth is OAuth) {
+        auth.setAccessToken(accessToken);
+      }
+    });
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
new file mode 100644
index 00000000000..c7c10a817a1
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/api_doc.mustache
@@ -0,0 +1,86 @@
+# {{pubName}}.api.{{classname}}{{#description}}
+{{description}}{{/description}}
+
+## Load the API package
+```dart
+import 'package:{{pubName}}/api.dart';
+```
+
+All URIs are relative to *{{basePath}}*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationId}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
+{{/operation}}{{/operations}}
+
+{{#operations}}
+{{#operation}}
+# **{{{operationId}}}**
+> {{#returnType}}{{{returnType}}} {{/returnType}}{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}})
+
+{{{summary}}}{{#notes}}
+
+{{{notes}}}{{/notes}}
+
+### Example 
+```dart
+import 'package:{{pubName}}/api.dart';
+{{#hasAuthMethods}}
+{{#authMethods}}
+{{#isBasic}}
+// TODO Configure HTTP basic authorization: {{{name}}}
+//{{pubName}}.api.Configuration.username = 'YOUR_USERNAME';
+//{{pubName}}.api.Configuration.password = 'YOUR_PASSWORD';
+{{/isBasic}}
+{{#isApiKey}}
+// TODO Configure API key authorization: {{{name}}}
+//{{pubName}}.api.Configuration.apiKey{'{{{keyParamName}}}'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//{{pubName}}.api.Configuration.apiKeyPrefix{'{{{keyParamName}}}'} = "Bearer";
+{{/isApiKey}}
+{{#isOAuth}}
+// TODO Configure OAuth2 access token for authorization: {{{name}}}
+//{{pubName}}.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+{{/isOAuth}}
+{{/authMethods}}
+{{/hasAuthMethods}}
+
+var api_instance = new {{classname}}();
+{{#allParams}}
+var {{paramName}} = {{#isListContainer}}[{{/isListContainer}}{{#isBodyParam}}new {{dataType}}(){{/isBodyParam}}{{^isBodyParam}}{{{example}}}{{/isBodyParam}}{{#isListContainer}}]{{/isListContainer}}; // {{{dataType}}} | {{{description}}}
+{{/allParams}}
+
+try { 
+    {{#returnType}}var result = {{/returnType}}api_instance.{{{operationId}}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}});
+    {{#returnType}}
+    print(result);
+    {{/returnType}}
+} catch (e) {
+    print("Exception when calling {{classname}}->{{operationId}}: $e\n");
+}
+```
+
+### Parameters
+{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
+{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{baseType}}.md){{/isPrimitiveType}}| {{description}} | {{^required}}[optional] {{/required}}{{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}
+{{/allParams}}
+
+### Return type
+
+{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}void (empty response body){{/returnType}}
+
+### Authorization
+
+{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}
+
+### HTTP request headers
+
+ - **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
+ - **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+{{/operation}}
+{{/operations}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache b/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache
new file mode 100644
index 00000000000..5964f88f93d
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/api_exception.mustache
@@ -0,0 +1,23 @@
+part of {{pubName}}.api;
+
+class ApiException implements Exception {
+  int code = 0;
+  String message;
+  Exception innerException;
+  StackTrace stackTrace;
+
+  ApiException(this.code, this.message);
+
+  ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace);
+
+  String toString() {
+    if (message == null) return "ApiException";
+
+    if (innerException == null) {
+      return "ApiException $code: $message";
+    }
+
+    return "ApiException $code: $message (Inner exception: $innerException)\n\n" +
+        stackTrace.toString();
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache b/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache
new file mode 100644
index 00000000000..1e554bede4b
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/api_helper.mustache
@@ -0,0 +1,52 @@
+part of {{pubName}}.api;
+
+const _delimiters = const {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
+
+// port from Java version
+Iterable<QueryParam> _convertParametersForCollectionFormat(
+  String collectionFormat, String name, dynamic value) {
+  var params = <QueryParam>[];
+
+  // preconditions
+  if (name == null || name.isEmpty || value == null) return params;
+
+  if (value is! List) {
+    params.add(QueryParam(name, parameterToString(value)));
+    return params;
+  }
+
+  List values = value as List;
+
+  // get the collection format
+  collectionFormat = (collectionFormat == null || collectionFormat.isEmpty)
+                     ? "csv"
+                     : collectionFormat; // default: csv
+
+  if (collectionFormat == "multi") {
+    return values.map((v) => QueryParam(name, parameterToString(v)));
+  }
+
+  String delimiter = _delimiters[collectionFormat] ?? ",";
+
+  params.add(QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  return params;
+}
+
+/// Format the given parameter object into string.
+String parameterToString(dynamic value) {
+  if (value == null) {
+    return '';
+  } else if (value is DateTime) {
+    return value.toUtc().toIso8601String();
+  {{#models}}
+    {{#model}}
+      {{#isEnum}}
+  } else if (value is {{classname}}) {
+    return {{classname}}TypeTransformer().encode(value).toString();
+      {{/isEnum}}
+    {{/model}}
+  {{/models}}
+  } else {
+    return value.toString();
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/apilib.mustache b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache
new file mode 100644
index 00000000000..577330e54cb
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/apilib.mustache
@@ -0,0 +1,21 @@
+library {{pubName}}.api;
+
+import 'dart:async';
+import 'dart:convert';{{#browserClient}}
+import 'package:http/browser_client.dart';{{/browserClient}}
+import 'package:http/http.dart';
+
+part 'api_client.dart';
+part 'api_helper.dart';
+part 'api_exception.dart';
+part 'auth/authentication.dart';
+part 'auth/api_key_auth.dart';
+part 'auth/oauth.dart';
+part 'auth/http_basic_auth.dart';
+
+{{#apiInfo}}{{#apis}}part 'api/{{classFilename}}.dart';
+{{/apis}}{{/apiInfo}}
+{{#models}}{{#model}}part 'model/{{classFilename}}.dart';
+{{/model}}{{/models}}
+
+ApiClient defaultApiClient = ApiClient();
diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache
new file mode 100644
index 00000000000..1e62a7902e4
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/auth/api_key_auth.mustache
@@ -0,0 +1,27 @@
+part of {{pubName}}.api;
+
+class ApiKeyAuth implements Authentication {
+
+  final String location;
+  final String paramName;
+  String apiKey;
+  String apiKeyPrefix;
+
+  ApiKeyAuth(this.location, this.paramName);
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String value;
+    if (apiKeyPrefix != null) {
+      value = '$apiKeyPrefix $apiKey';
+    } else {
+      value = apiKey;
+    }
+
+    if (location == 'query' && value != null) {
+      queryParams.add(QueryParam(paramName, value));
+    } else if (location == 'header' && value != null) {
+      headerParams[paramName] = value;
+    }
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache
new file mode 100644
index 00000000000..00bbbf09746
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/auth/authentication.mustache
@@ -0,0 +1,7 @@
+part of {{pubName}}.api;
+
+abstract class Authentication {
+
+	/// Apply authentication settings to header and query params.
+	void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams);
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache
new file mode 100644
index 00000000000..89b3926ed79
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/auth/http_basic_auth.mustache
@@ -0,0 +1,14 @@
+part of {{pubName}}.api;
+
+class HttpBasicAuth implements Authentication {
+
+  String username;
+  String password;
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
+    headerParams["Authorization"] = "Basic " + base64.encode(utf8.encode(str));
+  }
+
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache
new file mode 100644
index 00000000000..07a25e5f6dc
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/auth/oauth.mustache
@@ -0,0 +1,18 @@
+part of {{pubName}}.api;
+
+class OAuth implements Authentication {
+  String accessToken;
+
+  OAuth({this.accessToken});
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    if (accessToken != null) {
+      headerParams["Authorization"] = "Bearer " + accessToken;
+    }
+  }
+
+  void setAccessToken(String accessToken) {
+    this.accessToken = accessToken;
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/class.mustache b/modules/openapi-generator/src/main/resources/dart2/class.mustache
new file mode 100644
index 00000000000..c13f51c33d5
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/class.mustache
@@ -0,0 +1,82 @@
+class {{classname}} {
+  {{#vars}}
+  {{#description}}/* {{{description}}} */{{/description}}
+  {{{dataType}}} {{name}};
+  {{#allowableValues}}
+  {{#min}} // range from {{min}} to {{max}}{{/min}}//{{^min}}enum {{name}}Enum { {{#values}} {{.}}, {{/values}} };{{/min}}{
+  {{/allowableValues}}
+  {{/vars}}
+  {{classname}}();
+
+  @override
+  String toString() {
+    return '{{classname}}[{{#vars}}{{name}}=${{name}}, {{/vars}}]';
+  }
+
+  {{classname}}.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+  {{#vars}}
+  {{#isDateTime}}
+    {{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
+  {{/isDateTime}}
+  {{#isDate}}
+    {{name}} = json['{{baseName}}'] == null ? null : DateTime.parse(json['{{baseName}}']);
+  {{/isDate}}
+  {{^isDateTime}}
+  {{^isDate}}
+    {{#complexType}}
+      {{#isListContainer}}
+    {{name}} = {{complexType}}.listFromJson(json['{{baseName}}']);
+      {{/isListContainer}}
+      {{^isListContainer}}
+      {{#isMapContainer}}
+    {{name}} = {{complexType}}.mapFromJson(json['{{baseName}}']);
+      {{/isMapContainer}}
+      {{^isMapContainer}}
+    {{name}} = new {{complexType}}.fromJson(json['{{baseName}}']);
+      {{/isMapContainer}}
+      {{/isListContainer}}
+    {{/complexType}}
+    {{^complexType}}
+      {{#isListContainer}}
+    {{name}} = (json['{{baseName}}'] as List).map((item) => item as {{items.datatype}}).toList();
+      {{/isListContainer}}
+      {{^isListContainer}}
+    {{name}} = json['{{baseName}}'];
+      {{/isListContainer}}
+    {{/complexType}}
+  {{/isDate}}
+  {{/isDateTime}}
+  {{/vars}}
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+    {{#vars}}
+      {{#isDateTime}}
+      '{{baseName}}': {{name}} == null ? '' : {{name}}.toUtc().toIso8601String(){{^-last}},{{/-last}}
+      {{/isDateTime}}
+      {{#isDate}}
+      '{{baseName}}': {{name}} == null ? '' : {{name}}.toUtc().toIso8601String(){{^-last}},{{/-last}}
+      {{/isDate}}
+      {{^isDateTime}}
+      {{^isDate}}
+      '{{baseName}}': {{name}}{{^-last}},{{/-last}}
+      {{/isDate}}
+      {{/isDateTime}}
+    {{/vars}}
+    };
+  }
+
+  static List<{{classname}}> listFromJson(List<dynamic> json) {
+    return json == null ? new List<{{classname}}>() : json.map((value) => new {{classname}}.fromJson(value)).toList();
+  }
+
+  static Map<String, {{classname}}> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, {{classname}}>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new {{classname}}.fromJson(value));
+    }
+    return map;
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/enum.mustache b/modules/openapi-generator/src/main/resources/dart2/enum.mustache
new file mode 100644
index 00000000000..debb73bbcec
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/enum.mustache
@@ -0,0 +1,36 @@
+@Entity()
+class {{classname}} {
+  /// The underlying value of this enum member.
+  final {{dataType}} value;
+
+  const {{classname}}._internal(this.value);
+
+  {{#allowableValues}}
+    {{#enumVars}}
+      {{#description}}
+  /// {{description}}
+      {{/description}}
+  static const {{classname}} {{name}} = const {{classname}}._internal({{value}});
+    {{/enumVars}}
+  {{/allowableValues}}
+}
+
+class {{classname}}TypeTransformer extends TypeTransformer<{{classname}}> {
+
+  @override
+  dynamic encode({{classname}} data) {
+    return data.value;
+  }
+
+  @override
+  {{classname}} decode(dynamic data) {
+    switch (data) {
+      {{#allowableValues}}
+        {{#enumVars}}
+      case {{value}}: return {{classname}}.{{name}};
+        {{/enumVars}}
+      {{/allowableValues}}
+      default: throw('Unknown enum value to decode: $data');
+    }
+  }
+}
diff --git a/modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache b/modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache
new file mode 100755
index 00000000000..8a32e53995d
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/git_push.sh.mustache
@@ -0,0 +1,52 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+
+if [ "$git_user_id" = "" ]; then
+    git_user_id="{{{gitUserId}}}"
+    echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+    git_repo_id="{{{gitRepoId}}}"
+    echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+    release_note="{{{releaseNote}}}"
+    echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository. 
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=`git remote`
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+    if [ "$GIT_TOKEN" = "" ]; then
+        echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+        git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
+    else
+        git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
+    fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
+
diff --git a/modules/openapi-generator/src/main/resources/dart2/gitignore.mustache b/modules/openapi-generator/src/main/resources/dart2/gitignore.mustache
new file mode 100644
index 00000000000..7c280441649
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/gitignore.mustache
@@ -0,0 +1,27 @@
+# See https://www.dartlang.org/tools/private-files.html
+
+# Files and directories created by pub
+.buildlog
+.packages
+.project
+.pub/
+build/
+**/packages/
+
+# Files created by dart2js
+# (Most Dart developers will use pub build to compile Dart, use/modify these 
+#  rules if you intend to use dart2js directly
+#  Convention is to use extension '.dart.js' for Dart compiled to Javascript to
+#  differentiate from explicit Javascript files)
+*.dart.js
+*.part.js
+*.js.deps
+*.js.map
+*.info.json
+
+# Directory created by dartdoc
+doc/api/
+
+# Don't commit pubspec lock file 
+# (Library packages only! Remove pattern if developing an application package)
+pubspec.lock
diff --git a/modules/openapi-generator/src/main/resources/dart2/model.mustache b/modules/openapi-generator/src/main/resources/dart2/model.mustache
new file mode 100644
index 00000000000..37b030ab034
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/model.mustache
@@ -0,0 +1,12 @@
+part of {{pubName}}.api;
+
+{{#models}}
+{{#model}}
+{{#isEnum}}
+{{>enum}}
+{{/isEnum}}
+{{^isEnum}}
+{{>class}}
+{{/isEnum}}
+{{/model}}
+{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/object_doc.mustache b/modules/openapi-generator/src/main/resources/dart2/object_doc.mustache
new file mode 100644
index 00000000000..657f84d8905
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/object_doc.mustache
@@ -0,0 +1,16 @@
+{{#models}}{{#model}}# {{pubName}}.model.{{classname}}
+
+## Load the model package
+```dart
+import 'package:{{pubName}}/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+{{#vars}}**{{name}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{complexType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}
+{{/vars}}
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+{{/model}}{{/models}}
diff --git a/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache b/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache
new file mode 100644
index 00000000000..a338854b748
--- /dev/null
+++ b/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache
@@ -0,0 +1,5 @@
+name: {{pubName}}
+version: {{pubVersion}}
+description: {{pubDescription}}
+dependencies:
+  http: '>=0.11.1 <0.12.0'
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java
index b23cf14f227..42167695ec8 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/options/DartClientOptionsProvider.java
@@ -54,6 +54,7 @@ public class DartClientOptionsProvider implements OptionsProvider {
                 .put(DartClientCodegen.USE_ENUM_EXTENSION, USE_ENUM_EXTENSION)
                 .put(CodegenConstants.ALLOW_UNICODE_IDENTIFIERS, ALLOW_UNICODE_IDENTIFIERS_VALUE)
                 .put(CodegenConstants.PREPEND_FORM_OR_BODY_PARAMETERS, PREPEND_FORM_OR_BODY_PARAMETERS_VALUE)
+                .put(DartClientCodegen.SUPPORT_DART2, "false")
                 .build();
     }
 
-- 
GitLab


From d4c810988a90fc11477539b2cd008e01e85e7243 Mon Sep 17 00:00:00 2001
From: William Cheng <wing328hk@gmail.com>
Date: Fri, 24 Aug 2018 11:23:39 +0800
Subject: [PATCH 02/16] add dart2 samples, update travis

---
 .travis.yml                                   |   7 +-
 bin/dart2-petstore.sh                         |  50 ++
 pom.xml                                       |   1 +
 .../openapi/.analysis_options                 |   2 +
 .../dart2/flutter_petstore/openapi/.gitignore |  27 ++
 .../openapi/.openapi-generator-ignore         |  23 +
 .../openapi/.openapi-generator/VERSION        |   1 +
 .../dart2/flutter_petstore/openapi/README.md  | 121 +++++
 .../openapi/docs/ApiResponse.md               |  17 +
 .../flutter_petstore/openapi/docs/Category.md |  16 +
 .../flutter_petstore/openapi/docs/Order.md    |  20 +
 .../flutter_petstore/openapi/docs/Pet.md      |  20 +
 .../flutter_petstore/openapi/docs/PetApi.md   | 379 +++++++++++++++
 .../flutter_petstore/openapi/docs/StoreApi.md | 186 ++++++++
 .../flutter_petstore/openapi/docs/Tag.md      |  16 +
 .../flutter_petstore/openapi/docs/User.md     |  22 +
 .../flutter_petstore/openapi/docs/UserApi.md  | 349 ++++++++++++++
 .../flutter_petstore/openapi/git_push.sh      |  52 +++
 .../flutter_petstore/openapi/lib/api.dart     |  27 ++
 .../openapi/lib/api/pet_api.dart              | 432 ++++++++++++++++++
 .../openapi/lib/api/store_api.dart            | 207 +++++++++
 .../openapi/lib/api/user_api.dart             | 409 +++++++++++++++++
 .../openapi/lib/api_client.dart               | 160 +++++++
 .../openapi/lib/api_exception.dart            |  23 +
 .../openapi/lib/api_helper.dart               |  44 ++
 .../openapi/lib/auth/api_key_auth.dart        |  27 ++
 .../openapi/lib/auth/authentication.dart      |   7 +
 .../openapi/lib/auth/http_basic_auth.dart     |  14 +
 .../openapi/lib/auth/oauth.dart               |  19 +
 .../openapi/lib/model/api_response.dart       |  44 ++
 .../openapi/lib/model/category.dart           |  40 ++
 .../openapi/lib/model/order.dart              |  57 +++
 .../openapi/lib/model/pet.dart                |  57 +++
 .../openapi/lib/model/tag.dart                |  40 ++
 .../openapi/lib/model/user.dart               |  64 +++
 .../flutter_petstore/openapi/pubspec.yaml     |   5 +
 .../openapi-browser-client/.analysis_options  |   2 +
 .../dart2/openapi-browser-client/.gitignore   |  27 ++
 .../.openapi-generator-ignore                 |  23 +
 .../.openapi-generator/VERSION                |   1 +
 .../dart2/openapi-browser-client/README.md    | 121 +++++
 .../docs/ApiResponse.md                       |  17 +
 .../openapi-browser-client/docs/Category.md   |  16 +
 .../openapi-browser-client/docs/Order.md      |  20 +
 .../dart2/openapi-browser-client/docs/Pet.md  |  20 +
 .../openapi-browser-client/docs/PetApi.md     | 379 +++++++++++++++
 .../openapi-browser-client/docs/StoreApi.md   | 186 ++++++++
 .../dart2/openapi-browser-client/docs/Tag.md  |  16 +
 .../dart2/openapi-browser-client/docs/User.md |  22 +
 .../openapi-browser-client/docs/UserApi.md    | 349 ++++++++++++++
 .../dart2/openapi-browser-client/git_push.sh  |  52 +++
 .../dart2/openapi-browser-client/lib/api.dart |  28 ++
 .../lib/api/pet_api.dart                      | 432 ++++++++++++++++++
 .../lib/api/store_api.dart                    | 207 +++++++++
 .../lib/api/user_api.dart                     | 409 +++++++++++++++++
 .../lib/api_client.dart                       | 160 +++++++
 .../lib/api_exception.dart                    |  23 +
 .../lib/api_helper.dart                       |  44 ++
 .../lib/auth/api_key_auth.dart                |  27 ++
 .../lib/auth/authentication.dart              |   7 +
 .../lib/auth/http_basic_auth.dart             |  14 +
 .../lib/auth/oauth.dart                       |  19 +
 .../lib/model/api_response.dart               |  44 ++
 .../lib/model/category.dart                   |  40 ++
 .../lib/model/order.dart                      |  57 +++
 .../openapi-browser-client/lib/model/pet.dart |  57 +++
 .../openapi-browser-client/lib/model/tag.dart |  40 ++
 .../lib/model/user.dart                       |  64 +++
 .../dart2/openapi-browser-client/pubspec.yaml |   5 +
 .../petstore/dart2/openapi/.analysis_options  |   2 +
 .../client/petstore/dart2/openapi/.gitignore  |  27 ++
 .../dart2/openapi/.openapi-generator-ignore   |  23 +
 .../dart2/openapi/.openapi-generator/VERSION  |   1 +
 .../client/petstore/dart2/openapi/README.md   | 121 +++++
 .../dart2/openapi/docs/ApiResponse.md         |  17 +
 .../petstore/dart2/openapi/docs/Category.md   |  16 +
 .../petstore/dart2/openapi/docs/Order.md      |  20 +
 .../client/petstore/dart2/openapi/docs/Pet.md |  20 +
 .../petstore/dart2/openapi/docs/PetApi.md     | 379 +++++++++++++++
 .../petstore/dart2/openapi/docs/StoreApi.md   | 186 ++++++++
 .../client/petstore/dart2/openapi/docs/Tag.md |  16 +
 .../petstore/dart2/openapi/docs/User.md       |  22 +
 .../petstore/dart2/openapi/docs/UserApi.md    | 349 ++++++++++++++
 .../client/petstore/dart2/openapi/git_push.sh |  52 +++
 .../petstore/dart2/openapi/lib/api.dart       |  27 ++
 .../dart2/openapi/lib/api/pet_api.dart        | 432 ++++++++++++++++++
 .../dart2/openapi/lib/api/store_api.dart      | 207 +++++++++
 .../dart2/openapi/lib/api/user_api.dart       | 409 +++++++++++++++++
 .../dart2/openapi/lib/api_client.dart         | 160 +++++++
 .../dart2/openapi/lib/api_exception.dart      |  23 +
 .../dart2/openapi/lib/api_helper.dart         |  44 ++
 .../dart2/openapi/lib/auth/api_key_auth.dart  |  27 ++
 .../openapi/lib/auth/authentication.dart      |   7 +
 .../openapi/lib/auth/http_basic_auth.dart     |  14 +
 .../dart2/openapi/lib/auth/oauth.dart         |  19 +
 .../dart2/openapi/lib/model/api_response.dart |  44 ++
 .../dart2/openapi/lib/model/category.dart     |  40 ++
 .../dart2/openapi/lib/model/order.dart        |  57 +++
 .../petstore/dart2/openapi/lib/model/pet.dart |  57 +++
 .../petstore/dart2/openapi/lib/model/tag.dart |  40 ++
 .../dart2/openapi/lib/model/user.dart         |  64 +++
 .../petstore/dart2/openapi/pubspec.yaml       |   5 +
 .../petstore/dart2/petstore/.analysis_options |   2 +
 .../client/petstore/dart2/petstore/README.md  |  58 +++
 .../client/petstore/dart2/petstore/pom.xml    |  60 +++
 .../petstore/dart2/petstore/pubspec.yaml      |   9 +
 .../dart2/petstore/test/pet_test.dart         |  81 ++++
 .../dart2/petstore/test/store_test.dart       |  28 ++
 .../petstore/dart2/petstore/test/tests.dart   |  23 +
 .../petstore/dart2/petstore/test/tests.html   |  14 +
 .../dart2/petstore/test/user_test.dart        |  77 ++++
 111 files changed, 9191 insertions(+), 1 deletion(-)
 create mode 100755 bin/dart2-petstore.sh
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/.analysis_options
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/.gitignore
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator-ignore
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator/VERSION
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/README.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/ApiResponse.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/Category.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/Order.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/Pet.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/PetApi.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/StoreApi.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/Tag.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/User.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/docs/UserApi.md
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/git_push.sh
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/authentication.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/api_response.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/category.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/order.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/tag.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/user.dart
 create mode 100644 samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/.analysis_options
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/.gitignore
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/.openapi-generator-ignore
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/.openapi-generator/VERSION
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/README.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/ApiResponse.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/Category.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/Order.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/Pet.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/PetApi.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/StoreApi.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/Tag.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/User.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/docs/UserApi.md
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/git_push.sh
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/auth/authentication.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/api_response.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/category.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/order.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/tag.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/lib/model/user.dart
 create mode 100644 samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
 create mode 100644 samples/client/petstore/dart2/openapi/.analysis_options
 create mode 100644 samples/client/petstore/dart2/openapi/.gitignore
 create mode 100644 samples/client/petstore/dart2/openapi/.openapi-generator-ignore
 create mode 100644 samples/client/petstore/dart2/openapi/.openapi-generator/VERSION
 create mode 100644 samples/client/petstore/dart2/openapi/README.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/ApiResponse.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/Category.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/Order.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/Pet.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/PetApi.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/StoreApi.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/Tag.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/User.md
 create mode 100644 samples/client/petstore/dart2/openapi/docs/UserApi.md
 create mode 100644 samples/client/petstore/dart2/openapi/git_push.sh
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api/store_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api/user_api.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api_client.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api_exception.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/api_helper.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/auth/authentication.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/api_response.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/category.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/order.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/pet.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/tag.dart
 create mode 100644 samples/client/petstore/dart2/openapi/lib/model/user.dart
 create mode 100644 samples/client/petstore/dart2/openapi/pubspec.yaml
 create mode 100644 samples/client/petstore/dart2/petstore/.analysis_options
 create mode 100644 samples/client/petstore/dart2/petstore/README.md
 create mode 100644 samples/client/petstore/dart2/petstore/pom.xml
 create mode 100644 samples/client/petstore/dart2/petstore/pubspec.yaml
 create mode 100644 samples/client/petstore/dart2/petstore/test/pet_test.dart
 create mode 100644 samples/client/petstore/dart2/petstore/test/store_test.dart
 create mode 100644 samples/client/petstore/dart2/petstore/test/tests.dart
 create mode 100644 samples/client/petstore/dart2/petstore/test/tests.html
 create mode 100644 samples/client/petstore/dart2/petstore/test/user_test.dart

diff --git a/.travis.yml b/.travis.yml
index 159d08b7a1c..fa01bd2528a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,6 +30,7 @@ cache:
   - $HOME/perl5
   - $HOME/.cargo
   - $HOME/.stack
+  - $HOME/.pub-cache
   - $HOME/samples/server/petstore/cpp-pistache/pistache
 
 services:
@@ -70,6 +71,8 @@ before_install:
   - sudo apt-get update -qq
   - sudo apt-get install -qq bats
   - sudo apt-get install -qq curl
+  # install dart
+  - sudo apt-get install dart
   # install perl module
   #- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
   #- cpanm Test::Exception Test::More Log::Any LWP::UserAgent JSON URI:Query Module::Runtime DateTime Module::Find Moose::Role
@@ -94,11 +97,13 @@ install:
   # Add Godeps dependencies to GOPATH and PATH
   #- eval "$(curl -sL https://raw.githubusercontent.com/travis-ci/gimme/master/gimme | GIMME_GO_VERSION=1.4 bash)"
   #- export GOPATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace"
-  - export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$HOME/.cargo/bin:$PATH"
+  - export PATH="${TRAVIS_BUILD_DIR}/Godeps/_workspace/bin:$HOME/.cargo/bin:$PATH:/usr/lib/dart/bin"
   #- go version
   - gcc -v
   - echo $CC
   - echo $CXX
+  - pub version
+  - dart --version
 
 script:
   # fail fast
diff --git a/bin/dart2-petstore.sh b/bin/dart2-petstore.sh
new file mode 100755
index 00000000000..8c415b9b1bd
--- /dev/null
+++ b/bin/dart2-petstore.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+SCRIPT="$0"
+echo "# START SCRIPT: $SCRIPT"
+
+while [ -h "$SCRIPT" ] ; do
+  ls=`ls -ld "$SCRIPT"`
+  link=`expr "$ls" : '.*-> \(.*\)$'`
+  if expr "$link" : '/.*' > /dev/null; then
+    SCRIPT="$link"
+  else
+    SCRIPT=`dirname "$SCRIPT"`/"$link"
+  fi
+done
+
+if [ ! -d "${APP_DIR}" ]; then
+  APP_DIR=`dirname "$SCRIPT"`/..
+  APP_DIR=`cd "${APP_DIR}"; pwd`
+fi
+
+executable="./modules/openapi-generator-cli/target/openapi-generator-cli.jar"
+
+if [ ! -f "$executable" ]
+then
+  mvn -B clean package
+fi
+
+# if you've executed sbt assembly previously it will use that instead.
+export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
+
+# Generate non-browserClient
+ags="generate -t modules/openapi-generator/src/main/resources/dart -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/openapi -DhideGenerationTimestamp=true -DbrowserClient=false --additional-properties supportDart2=true $@"
+
+# then options to generate the library for vm would be:
+#ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart/openapi_vm -DbrowserClient=false -DpubName=openapi_vm $@"
+java $JAVA_OPTS -jar $executable $ags
+
+# Generate browserClient
+ags="generate -t modules/openapi-generator/src/main/resources/dart -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/openapi-browser-client -DhideGenerationTimestamp=true -DbrowserClient=true --additional-properties supportDart2=true $@"
+java $JAVA_OPTS -jar $executable $ags
+
+# Generate non-browserClient and put it to the flutter sample app
+ags="generate -t modules/openapi-generator/src/main/resources/dart -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/flutter_petstore/openapi -DhideGenerationTimestamp=true -DbrowserClient=false --additional-properties supportDart2=true $@"
+java $JAVA_OPTS -jar $executable $ags
+
+# There is a proposal to allow importing different libraries depending on the environment:
+# https://github.com/munificent/dep-interface-libraries
+# When this is implemented there will only be one library.
+
+# The current petstore test will then work for both: the browser library and the vm library.
diff --git a/pom.xml b/pom.xml
index 97eb18cdc1a..626fe5cec71 100644
--- a/pom.xml
+++ b/pom.xml
@@ -978,6 +978,7 @@
             </activation>
             <modules>
                 <!-- clients -->
+                <module>samples/client/petstore/dart2/petstore</module>
                 <module>samples/client/petstore/haskell-http-client</module>
                 <module>samples/client/petstore/elm</module>
                 <module>samples/client/petstore/groovy</module>
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/.analysis_options b/samples/client/petstore/dart2/flutter_petstore/openapi/.analysis_options
new file mode 100644
index 00000000000..518eb901a6f
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/.gitignore b/samples/client/petstore/dart2/flutter_petstore/openapi/.gitignore
new file mode 100644
index 00000000000..7c280441649
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/.gitignore
@@ -0,0 +1,27 @@
+# See https://www.dartlang.org/tools/private-files.html
+
+# Files and directories created by pub
+.buildlog
+.packages
+.project
+.pub/
+build/
+**/packages/
+
+# Files created by dart2js
+# (Most Dart developers will use pub build to compile Dart, use/modify these 
+#  rules if you intend to use dart2js directly
+#  Convention is to use extension '.dart.js' for Dart compiled to Javascript to
+#  differentiate from explicit Javascript files)
+*.dart.js
+*.part.js
+*.js.deps
+*.js.map
+*.info.json
+
+# Directory created by dartdoc
+doc/api/
+
+# Don't commit pubspec lock file 
+# (Library packages only! Remove pattern if developing an application package)
+pubspec.lock
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator-ignore b/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator-ignore
new file mode 100644
index 00000000000..7484ee590a3
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator/VERSION b/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator/VERSION
new file mode 100644
index 00000000000..105bb87d77b
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/.openapi-generator/VERSION
@@ -0,0 +1 @@
+3.2.2-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/README.md b/samples/client/petstore/dart2/flutter_petstore/openapi/README.md
new file mode 100644
index 00000000000..5f3fe054784
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/README.md
@@ -0,0 +1,121 @@
+# openapi
+This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+
+This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: 1.0.0
+- Build package: org.openapitools.codegen.languages.DartClientCodegen
+
+## Requirements
+
+Dart 1.20.0 or later OR Flutter 0.0.20 or later
+
+## Installation & Usage
+
+### Github
+If this Dart package is published to Github, please include the following in pubspec.yaml
+```
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  openapi:
+    git: https://github.com/GIT_USER_ID/GIT_REPO_ID.git
+      version: 'any'
+```
+
+### Local
+To use the package in your local drive, please include the following in pubspec.yaml
+```
+dependencies:
+  openapi:
+    path: /path/to/openapi
+```
+
+## Tests
+
+TODO
+
+## Getting Started
+
+Please follow the [installation procedure](#installation--usage) and then run the following:
+
+```dart
+import 'package:openapi/api.dart';
+
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try {
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*PetApi* | [**addPet**](docs//PetApi.md#addpet) | **POST** /pet | Add a new pet to the store
+*PetApi* | [**deletePet**](docs//PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet
+*PetApi* | [**findPetsByStatus**](docs//PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status
+*PetApi* | [**findPetsByTags**](docs//PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags
+*PetApi* | [**getPetById**](docs//PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID
+*PetApi* | [**updatePet**](docs//PetApi.md#updatepet) | **PUT** /pet | Update an existing pet
+*PetApi* | [**updatePetWithForm**](docs//PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data
+*PetApi* | [**uploadFile**](docs//PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image
+*StoreApi* | [**deleteOrder**](docs//StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+*StoreApi* | [**getInventory**](docs//StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status
+*StoreApi* | [**getOrderById**](docs//StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID
+*StoreApi* | [**placeOrder**](docs//StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet
+*UserApi* | [**createUser**](docs//UserApi.md#createuser) | **POST** /user | Create user
+*UserApi* | [**createUsersWithArrayInput**](docs//UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array
+*UserApi* | [**createUsersWithListInput**](docs//UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array
+*UserApi* | [**deleteUser**](docs//UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user
+*UserApi* | [**getUserByName**](docs//UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name
+*UserApi* | [**loginUser**](docs//UserApi.md#loginuser) | **GET** /user/login | Logs user into the system
+*UserApi* | [**logoutUser**](docs//UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session
+*UserApi* | [**updateUser**](docs//UserApi.md#updateuser) | **PUT** /user/{username} | Updated user
+
+
+## Documentation For Models
+
+ - [ApiResponse](docs//ApiResponse.md)
+ - [Category](docs//Category.md)
+ - [Order](docs//Order.md)
+ - [Pet](docs//Pet.md)
+ - [Tag](docs//Tag.md)
+ - [User](docs//User.md)
+
+
+## Documentation For Authorization
+
+
+## api_key
+
+- **Type**: API key
+- **API key parameter name**: api_key
+- **Location**: HTTP header
+
+## petstore_auth
+
+- **Type**: OAuth
+- **Flow**: implicit
+- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
+- **Scopes**: 
+ - **write:pets**: modify pets in your account
+ - **read:pets**: read your pets
+
+
+## Author
+
+
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/ApiResponse.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/ApiResponse.md
new file mode 100644
index 00000000000..92422f0f446
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/ApiResponse.md
@@ -0,0 +1,17 @@
+# openapi.model.ApiResponse
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**code** | **int** |  | [optional] [default to null]
+**type** | **String** |  | [optional] [default to null]
+**message** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Category.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Category.md
new file mode 100644
index 00000000000..cc0d1633b59
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Category.md
@@ -0,0 +1,16 @@
+# openapi.model.Category
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Order.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Order.md
new file mode 100644
index 00000000000..310ce6c65be
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Order.md
@@ -0,0 +1,20 @@
+# openapi.model.Order
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**petId** | **int** |  | [optional] [default to null]
+**quantity** | **int** |  | [optional] [default to null]
+**shipDate** | [**DateTime**](DateTime.md) |  | [optional] [default to null]
+**status** | **String** | Order Status | [optional] [default to null]
+**complete** | **bool** |  | [optional] [default to false]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Pet.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Pet.md
new file mode 100644
index 00000000000..191e1fc66a9
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Pet.md
@@ -0,0 +1,20 @@
+# openapi.model.Pet
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**category** | [**Category**](Category.md) |  | [optional] [default to null]
+**name** | **String** |  | [default to null]
+**photoUrls** | **List&lt;String&gt;** |  | [default to []]
+**tags** | [**List&lt;Tag&gt;**](Tag.md) |  | [optional] [default to []]
+**status** | **String** | pet status in the store | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/PetApi.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/PetApi.md
new file mode 100644
index 00000000000..6fa9abf67ae
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/PetApi.md
@@ -0,0 +1,379 @@
+# openapi.api.PetApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**addPet**](PetApi.md#addPet) | **POST** /pet | Add a new pet to the store
+[**deletePet**](PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet
+[**findPetsByStatus**](PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
+[**findPetsByTags**](PetApi.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags
+[**getPetById**](PetApi.md#getPetById) | **GET** /pet/{petId} | Find pet by ID
+[**updatePet**](PetApi.md#updatePet) | **PUT** /pet | Update an existing pet
+[**updatePetWithForm**](PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data
+[**uploadFile**](PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image
+
+
+# **addPet**
+> addPet(pet)
+
+Add a new pet to the store
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deletePet**
+> deletePet(petId, apiKey)
+
+Deletes a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | Pet id to delete
+var apiKey = apiKey_example; // String | 
+
+try { 
+    api_instance.deletePet(petId, apiKey);
+} catch (e) {
+    print("Exception when calling PetApi->deletePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| Pet id to delete | 
+ **apiKey** | **String**|  | [optional] 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByStatus**
+> List<Pet> findPetsByStatus(status)
+
+Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var status = []; // List<String> | Status values that need to be considered for filter
+
+try { 
+    var result = api_instance.findPetsByStatus(status);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByStatus: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **status** | [**List&lt;String&gt;**](String.md)| Status values that need to be considered for filter | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByTags**
+> List<Pet> findPetsByTags(tags)
+
+Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var tags = []; // List<String> | Tags to filter by
+
+try { 
+    var result = api_instance.findPetsByTags(tags);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByTags: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **tags** | [**List&lt;String&gt;**](String.md)| Tags to filter by | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getPetById**
+> Pet getPetById(petId)
+
+Find pet by ID
+
+Returns a single pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to return
+
+try { 
+    var result = api_instance.getPetById(petId);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->getPetById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to return | 
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePet**
+> updatePet(pet)
+
+Update an existing pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.updatePet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->updatePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePetWithForm**
+> updatePetWithForm(petId, name, status)
+
+Updates a pet in the store with form data
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet that needs to be updated
+var name = name_example; // String | Updated name of the pet
+var status = status_example; // String | Updated status of the pet
+
+try { 
+    api_instance.updatePetWithForm(petId, name, status);
+} catch (e) {
+    print("Exception when calling PetApi->updatePetWithForm: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet that needs to be updated | 
+ **name** | **String**| Updated name of the pet | [optional] [default to null]
+ **status** | **String**| Updated status of the pet | [optional] [default to null]
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/x-www-form-urlencoded
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **uploadFile**
+> ApiResponse uploadFile(petId, additionalMetadata, file)
+
+uploads an image
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to update
+var additionalMetadata = additionalMetadata_example; // String | Additional data to pass to server
+var file = BINARY_DATA_HERE; // MultipartFile | file to upload
+
+try { 
+    var result = api_instance.uploadFile(petId, additionalMetadata, file);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->uploadFile: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to update | 
+ **additionalMetadata** | **String**| Additional data to pass to server | [optional] [default to null]
+ **file** | **MultipartFile**| file to upload | [optional] [default to null]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/StoreApi.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/StoreApi.md
new file mode 100644
index 00000000000..cc0c2ac2d35
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/StoreApi.md
@@ -0,0 +1,186 @@
+# openapi.api.StoreApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**deleteOrder**](StoreApi.md#deleteOrder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+[**getInventory**](StoreApi.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status
+[**getOrderById**](StoreApi.md#getOrderById) | **GET** /store/order/{orderId} | Find purchase order by ID
+[**placeOrder**](StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet
+
+
+# **deleteOrder**
+> deleteOrder(orderId)
+
+Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = orderId_example; // String | ID of the order that needs to be deleted
+
+try { 
+    api_instance.deleteOrder(orderId);
+} catch (e) {
+    print("Exception when calling StoreApi->deleteOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **String**| ID of the order that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getInventory**
+> Map<String, int> getInventory()
+
+Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new StoreApi();
+
+try { 
+    var result = api_instance.getInventory();
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getInventory: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+**Map<String, int>**
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getOrderById**
+> Order getOrderById(orderId)
+
+Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = 789; // int | ID of pet that needs to be fetched
+
+try { 
+    var result = api_instance.getOrderById(orderId);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getOrderById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **int**| ID of pet that needs to be fetched | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **placeOrder**
+> Order placeOrder(order)
+
+Place an order for a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var order = new Order(); // Order | order placed for purchasing the pet
+
+try { 
+    var result = api_instance.placeOrder(order);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->placeOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **order** | [**Order**](Order.md)| order placed for purchasing the pet | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Tag.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Tag.md
new file mode 100644
index 00000000000..ded7b32ac3d
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/Tag.md
@@ -0,0 +1,16 @@
+# openapi.model.Tag
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/User.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/User.md
new file mode 100644
index 00000000000..3761b70cf0b
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/User.md
@@ -0,0 +1,22 @@
+# openapi.model.User
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**username** | **String** |  | [optional] [default to null]
+**firstName** | **String** |  | [optional] [default to null]
+**lastName** | **String** |  | [optional] [default to null]
+**email** | **String** |  | [optional] [default to null]
+**password** | **String** |  | [optional] [default to null]
+**phone** | **String** |  | [optional] [default to null]
+**userStatus** | **int** | User Status | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/docs/UserApi.md b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/UserApi.md
new file mode 100644
index 00000000000..0dec271be5c
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/docs/UserApi.md
@@ -0,0 +1,349 @@
+# openapi.api.UserApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**createUser**](UserApi.md#createUser) | **POST** /user | Create user
+[**createUsersWithArrayInput**](UserApi.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array
+[**createUsersWithListInput**](UserApi.md#createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array
+[**deleteUser**](UserApi.md#deleteUser) | **DELETE** /user/{username} | Delete user
+[**getUserByName**](UserApi.md#getUserByName) | **GET** /user/{username} | Get user by user name
+[**loginUser**](UserApi.md#loginUser) | **GET** /user/login | Logs user into the system
+[**logoutUser**](UserApi.md#logoutUser) | **GET** /user/logout | Logs out current logged in user session
+[**updateUser**](UserApi.md#updateUser) | **PUT** /user/{username} | Updated user
+
+
+# **createUser**
+> createUser(user)
+
+Create user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = new User(); // User | Created user object
+
+try { 
+    api_instance.createUser(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**User**](User.md)| Created user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithArrayInput**
+> createUsersWithArrayInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithArrayInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithArrayInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithListInput**
+> createUsersWithListInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithListInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithListInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deleteUser**
+> deleteUser(username)
+
+Delete user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be deleted
+
+try { 
+    api_instance.deleteUser(username);
+} catch (e) {
+    print("Exception when calling UserApi->deleteUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getUserByName**
+> User getUserByName(username)
+
+Get user by user name
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be fetched. Use user1 for testing.
+
+try { 
+    var result = api_instance.getUserByName(username);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->getUserByName: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be fetched. Use user1 for testing. | 
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **loginUser**
+> String loginUser(username, password)
+
+Logs user into the system
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The user name for login
+var password = password_example; // String | The password for login in clear text
+
+try { 
+    var result = api_instance.loginUser(username, password);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->loginUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The user name for login | 
+ **password** | **String**| The password for login in clear text | 
+
+### Return type
+
+**String**
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **logoutUser**
+> logoutUser()
+
+Logs out current logged in user session
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+
+try { 
+    api_instance.logoutUser();
+} catch (e) {
+    print("Exception when calling UserApi->logoutUser: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updateUser**
+> updateUser(username, user)
+
+Updated user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | name that need to be deleted
+var user = new User(); // User | Updated user object
+
+try { 
+    api_instance.updateUser(username, user);
+} catch (e) {
+    print("Exception when calling UserApi->updateUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| name that need to be deleted | 
+ **user** | [**User**](User.md)| Updated user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/git_push.sh b/samples/client/petstore/dart2/flutter_petstore/openapi/git_push.sh
new file mode 100644
index 00000000000..8442b80bb44
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/git_push.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+
+if [ "$git_user_id" = "" ]; then
+    git_user_id="GIT_USER_ID"
+    echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+    git_repo_id="GIT_REPO_ID"
+    echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+    release_note="Minor update"
+    echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository. 
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=`git remote`
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+    if [ "$GIT_TOKEN" = "" ]; then
+        echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+        git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
+    else
+        git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
+    fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
new file mode 100644
index 00000000000..9a64a5342b4
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
@@ -0,0 +1,27 @@
+library openapi.api;
+
+import 'dart:async';
+import 'dart:convert';
+import 'package:http/http.dart';
+
+part 'api_client.dart';
+part 'api_helper.dart';
+part 'api_exception.dart';
+part 'auth/authentication.dart';
+part 'auth/api_key_auth.dart';
+part 'auth/oauth.dart';
+part 'auth/http_basic_auth.dart';
+
+part 'api/pet_api.dart';
+part 'api/store_api.dart';
+part 'api/user_api.dart';
+
+part 'model/api_response.dart';
+part 'model/category.dart';
+part 'model/order.dart';
+part 'model/pet.dart';
+part 'model/tag.dart';
+part 'model/user.dart';
+
+
+ApiClient defaultApiClient = new ApiClient();
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
new file mode 100644
index 00000000000..4134e018386
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
@@ -0,0 +1,432 @@
+part of openapi.api;
+
+
+
+class PetApi {
+  final ApiClient apiClient;
+
+  PetApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Add a new pet to the store
+  ///
+  /// 
+  Future addPet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Deletes a pet
+  ///
+  /// 
+  Future deletePet(int petId, { String apiKey }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+    headerParams["api_key"] = apiKey;
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Finds Pets by status
+  ///
+  /// Multiple status values can be provided with comma separated strings
+  Future<List<Pet>> findPetsByStatus(List<String> status) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(status == null) {
+     throw new ApiException(400, "Missing required param: status");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByStatus".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "status", status));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Finds Pets by tags
+  ///
+  /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+  Future<List<Pet>> findPetsByTags(List<String> tags) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(tags == null) {
+     throw new ApiException(400, "Missing required param: tags");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByTags".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "tags", tags));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Find pet by ID
+  ///
+  /// Returns a single pet
+  Future<Pet> getPetById(int petId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Pet') as Pet;
+    } else {
+      return null;
+    }
+  }
+  /// Update an existing pet
+  ///
+  /// 
+  Future updatePet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updates a pet in the store with form data
+  ///
+  /// 
+  Future updatePetWithForm(int petId, { String name, String status }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/x-www-form-urlencoded"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (name != null) {
+        hasFields = true;
+        mp.fields['name'] = parameterToString(name);
+      }
+      if (status != null) {
+        hasFields = true;
+        mp.fields['status'] = parameterToString(status);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (name != null)
+        formParams['name'] = parameterToString(name);
+      if (status != null)
+        formParams['status'] = parameterToString(status);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// uploads an image
+  ///
+  /// 
+  Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}/uploadImage".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["multipart/form-data"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (additionalMetadata != null) {
+        hasFields = true;
+        mp.fields['additionalMetadata'] = parameterToString(additionalMetadata);
+      }
+      if (file != null) {
+        hasFields = true;
+        mp.fields['file'] = file.field;
+        mp.files.add(file);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (additionalMetadata != null)
+        formParams['additionalMetadata'] = parameterToString(additionalMetadata);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'ApiResponse') as ApiResponse;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
new file mode 100644
index 00000000000..f2a48f2d4da
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
@@ -0,0 +1,207 @@
+part of openapi.api;
+
+
+
+class StoreApi {
+  final ApiClient apiClient;
+
+  StoreApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Delete purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
+  Future deleteOrder(String orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Returns pet inventories by status
+  ///
+  /// Returns a map of status codes to quantities
+  Future<Map<String, int>> getInventory() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/store/inventory".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return new Map<String, int>.from(apiClient.deserialize(response.body, 'Map<String, int>'));
+          ;
+    } else {
+      return null;
+    }
+  }
+  /// Find purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
+  Future<Order> getOrderById(int orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+  /// Place an order for a pet
+  ///
+  /// 
+  Future<Order> placeOrder(Order order) async {
+    Object postBody = order;
+
+    // verify required params are set
+    if(order == null) {
+     throw new ApiException(400, "Missing required param: order");
+    }
+
+    // create path and map variables
+    String path = "/store/order".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
new file mode 100644
index 00000000000..cf8ef6bf800
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
@@ -0,0 +1,409 @@
+part of openapi.api;
+
+
+
+class UserApi {
+  final ApiClient apiClient;
+
+  UserApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Create user
+  ///
+  /// This can only be done by the logged in user.
+  Future createUser(User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithArrayInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithArray".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithListInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithList".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Delete user
+  ///
+  /// This can only be done by the logged in user.
+  Future deleteUser(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Get user by user name
+  ///
+  /// 
+  Future<User> getUserByName(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'User') as User;
+    } else {
+      return null;
+    }
+  }
+  /// Logs user into the system
+  ///
+  /// 
+  Future<String> loginUser(String username, String password) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(password == null) {
+     throw new ApiException(400, "Missing required param: password");
+    }
+
+    // create path and map variables
+    String path = "/user/login".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("", "username", username));
+      queryParams.addAll(_convertParametersForCollectionFormat("", "password", password));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'String') as String;
+    } else {
+      return null;
+    }
+  }
+  /// Logs out current logged in user session
+  ///
+  /// 
+  Future logoutUser() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/user/logout".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updated user
+  ///
+  /// This can only be done by the logged in user.
+  Future updateUser(String username, User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
new file mode 100644
index 00000000000..db4116dd96d
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
@@ -0,0 +1,160 @@
+part of openapi.api;
+
+class QueryParam {
+  String name;
+  String value;
+
+  QueryParam(this.name, this.value);
+}
+
+class ApiClient {
+
+  String basePath;
+  var client = new Client();
+
+  Map<String, String> _defaultHeaderMap = {};
+  Map<String, Authentication> _authentications = {};
+
+  final _RegList = new RegExp(r'^List<(.*)>$');
+  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+
+  ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
+    // Setup authentications (key: authentication name, value: authentication).
+    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = new OAuth();
+  }
+
+  void addDefaultHeader(String key, String value) {
+     _defaultHeaderMap[key] = value;
+  }
+
+  dynamic _deserialize(dynamic value, String targetType) {
+    try {
+      switch (targetType) {
+        case 'String':
+          return '$value';
+        case 'int':
+          return value is int ? value : int.parse('$value');
+        case 'bool':
+          return value is bool ? value : '$value'.toLowerCase() == 'true';
+        case 'double':
+          return value is double ? value : double.parse('$value');
+        case 'ApiResponse':
+          return new ApiResponse.fromJson(value);
+        case 'Category':
+          return new Category.fromJson(value);
+        case 'Order':
+          return new Order.fromJson(value);
+        case 'Pet':
+          return new Pet.fromJson(value);
+        case 'Tag':
+          return new Tag.fromJson(value);
+        case 'User':
+          return new User.fromJson(value);
+        default:
+          {
+            Match match;
+            if (value is List &&
+                (match = _RegList.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return value.map((v) => _deserialize(v, newTargetType)).toList();
+            } else if (value is Map &&
+                (match = _RegMap.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return new Map.fromIterables(value.keys,
+                  value.values.map((v) => _deserialize(v, newTargetType)));
+            }
+          }
+      }
+    } catch (e, stack) {
+      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+    }
+    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+  }
+
+  dynamic deserialize(String json, String targetType) {
+    // Remove all spaces.  Necessary for reg expressions as well.
+    targetType = targetType.replaceAll(' ', '');
+
+    if (targetType == 'String') return json;
+
+    var decodedJson = JSON.decode(json);
+    return _deserialize(decodedJson, targetType);
+  }
+
+  String serialize(Object obj) {
+    String serialized = '';
+    if (obj == null) {
+      serialized = '';
+    } else {
+      serialized = JSON.encode(obj);
+    }
+    return serialized;
+  }
+
+  // We don't use a Map<String, String> for queryParams.
+  // If collectionFormat is 'multi' a key might appear multiple times.
+  Future<Response> invokeAPI(String path,
+                             String method,
+                             Iterable<QueryParam> queryParams,
+                             Object body,
+                             Map<String, String> headerParams,
+                             Map<String, String> formParams,
+                             String contentType,
+                             List<String> authNames) async {
+
+    _updateParamsForAuth(authNames, queryParams, headerParams);
+
+    var ps = queryParams.where((p) => p.value != null).map((p) => '${p.name}=${p.value}');
+    String queryString = ps.isNotEmpty ?
+                         '?' + ps.join('&') :
+                         '';
+
+    String url = basePath + path + queryString;
+
+    headerParams.addAll(_defaultHeaderMap);
+    headerParams['Content-Type'] = contentType;
+
+    if(body is MultipartRequest) {
+      var request = new MultipartRequest(method, Uri.parse(url));
+      request.fields.addAll(body.fields);
+      request.files.addAll(body.files);
+      request.headers.addAll(body.headers);
+      request.headers.addAll(headerParams);
+      var response = await client.send(request);
+      return Response.fromStream(response);
+    } else {
+      var msgBody = contentType == "application/x-www-form-urlencoded" ? formParams : serialize(body);
+      switch(method) {
+        case "POST":
+          return client.post(url, headers: headerParams, body: msgBody);
+        case "PUT":
+          return client.put(url, headers: headerParams, body: msgBody);
+        case "DELETE":
+          return client.delete(url, headers: headerParams);
+        case "PATCH":
+          return client.patch(url, headers: headerParams, body: msgBody);
+        default:
+          return client.get(url, headers: headerParams);
+      }
+    }
+  }
+
+  /// Update query and header parameters based on authentication settings.
+  /// @param authNames The authentications to apply
+  void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
+    authNames.forEach((authName) {
+      Authentication auth = _authentications[authName];
+      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      auth.applyToParams(queryParams, headerParams);
+    });
+  }
+
+  void setAccessToken(String accessToken) {
+    _authentications.forEach((key, auth) {
+      if (auth is OAuth) {
+        auth.setAccessToken(accessToken);
+      }
+    });
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
new file mode 100644
index 00000000000..f188fd125a4
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
@@ -0,0 +1,23 @@
+part of openapi.api;
+
+class ApiException implements Exception {
+  int code = 0;
+  String message = null;
+  Exception innerException = null;
+  StackTrace stackTrace = null;
+
+  ApiException(this.code, this.message);
+
+  ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace);
+
+  String toString() {
+    if (message == null) return "ApiException";
+
+    if (innerException == null) {
+      return "ApiException $code: $message";
+    }
+
+    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+        stackTrace.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
new file mode 100644
index 00000000000..79af4521d5b
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+const _delimiters = const {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
+
+// port from Java version
+Iterable<QueryParam> _convertParametersForCollectionFormat(
+  String collectionFormat, String name, dynamic value) {
+  var params = <QueryParam>[];
+
+  // preconditions
+  if (name == null || name.isEmpty || value == null) return params;
+
+  if (value is! List) {
+    params.add(new QueryParam(name, parameterToString(value)));
+    return params;
+  }
+
+  List values = value as List;
+
+  // get the collection format
+  collectionFormat = (collectionFormat == null || collectionFormat.isEmpty)
+                     ? "csv"
+                     : collectionFormat; // default: csv
+
+  if (collectionFormat == "multi") {
+    return values.map((v) => new QueryParam(name, parameterToString(v)));
+  }
+
+  String delimiter = _delimiters[collectionFormat] ?? ",";
+
+  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  return params;
+}
+
+/// Format the given parameter object into string.
+String parameterToString(dynamic value) {
+  if (value == null) {
+    return '';
+  } else if (value is DateTime) {
+    return value.toUtc().toIso8601String();
+  } else {
+    return value.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
new file mode 100644
index 00000000000..f9617f7ae4d
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
@@ -0,0 +1,27 @@
+part of openapi.api;
+
+class ApiKeyAuth implements Authentication {
+
+  final String location;
+  final String paramName;
+  String apiKey;
+  String apiKeyPrefix;
+
+  ApiKeyAuth(this.location, this.paramName);
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String value;
+    if (apiKeyPrefix != null) {
+      value = '$apiKeyPrefix $apiKey';
+    } else {
+      value = apiKey;
+    }
+
+    if (location == 'query' && value != null) {
+      queryParams.add(new QueryParam(paramName, value));
+    } else if (location == 'header' && value != null) {
+      headerParams[paramName] = value;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/authentication.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/authentication.dart
new file mode 100644
index 00000000000..abd5e2fe68a
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/authentication.dart
@@ -0,0 +1,7 @@
+part of openapi.api;
+
+abstract class Authentication {
+
+	/// Apply authentication settings to header and query params.
+	void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams);
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
new file mode 100644
index 00000000000..4e77ddcf6e6
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
@@ -0,0 +1,14 @@
+part of openapi.api;
+
+class HttpBasicAuth implements Authentication {
+
+  String username;
+  String password;
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
+    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+  }
+
+}
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
new file mode 100644
index 00000000000..13bfd799743
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
@@ -0,0 +1,19 @@
+part of openapi.api;
+
+class OAuth implements Authentication {
+  String accessToken;
+
+  OAuth({this.accessToken}) {
+  }
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    if (accessToken != null) {
+      headerParams["Authorization"] = "Bearer " + accessToken;
+    }
+  }
+
+  void setAccessToken(String accessToken) {
+    this.accessToken = accessToken;
+  }
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/api_response.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/api_response.dart
new file mode 100644
index 00000000000..a39d9500b29
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/api_response.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+class ApiResponse {
+  
+  int code = null;
+  
+  String type = null;
+  
+  String message = null;
+  ApiResponse();
+
+  @override
+  String toString() {
+    return 'ApiResponse[code=$code, type=$type, message=$message, ]';
+  }
+
+  ApiResponse.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    code = json['code'];
+    type = json['type'];
+    message = json['message'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'code': code,
+      'type': type,
+      'message': message
+    };
+  }
+
+  static List<ApiResponse> listFromJson(List<dynamic> json) {
+    return json == null ? new List<ApiResponse>() : json.map((value) => new ApiResponse.fromJson(value)).toList();
+  }
+
+  static Map<String, ApiResponse> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, ApiResponse>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new ApiResponse.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/category.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/category.dart
new file mode 100644
index 00000000000..b9b2481dd29
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/category.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Category {
+  
+  int id = null;
+  
+  String name = null;
+  Category();
+
+  @override
+  String toString() {
+    return 'Category[id=$id, name=$name, ]';
+  }
+
+  Category.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Category> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Category>() : json.map((value) => new Category.fromJson(value)).toList();
+  }
+
+  static Map<String, Category> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Category>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Category.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/order.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/order.dart
new file mode 100644
index 00000000000..4e264a183ef
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/order.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Order {
+  
+  int id = null;
+  
+  int petId = null;
+  
+  int quantity = null;
+  
+  DateTime shipDate = null;
+  /* Order Status */
+  String status = null;
+  //enum statusEnum {  placed,  approved,  delivered,  };{
+  
+  bool complete = false;
+  Order();
+
+  @override
+  String toString() {
+    return 'Order[id=$id, petId=$petId, quantity=$quantity, shipDate=$shipDate, status=$status, complete=$complete, ]';
+  }
+
+  Order.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    petId = json['petId'];
+    quantity = json['quantity'];
+    shipDate = json['shipDate'] == null ? null : DateTime.parse(json['shipDate']);
+    status = json['status'];
+    complete = json['complete'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'petId': petId,
+      'quantity': quantity,
+      'shipDate': shipDate == null ? '' : shipDate.toUtc().toIso8601String(),
+      'status': status,
+      'complete': complete
+    };
+  }
+
+  static List<Order> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Order>() : json.map((value) => new Order.fromJson(value)).toList();
+  }
+
+  static Map<String, Order> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Order>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Order.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
new file mode 100644
index 00000000000..4d2f77a1a5a
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Pet {
+  
+  int id = null;
+  
+  Category category = null;
+  
+  String name = null;
+  
+  List<String> photoUrls = [];
+  
+  List<Tag> tags = [];
+  /* pet status in the store */
+  String status = null;
+  //enum statusEnum {  available,  pending,  sold,  };{
+  Pet();
+
+  @override
+  String toString() {
+    return 'Pet[id=$id, category=$category, name=$name, photoUrls=$photoUrls, tags=$tags, status=$status, ]';
+  }
+
+  Pet.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    category = new Category.fromJson(json['category']);
+    name = json['name'];
+    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    tags = Tag.listFromJson(json['tags']);
+    status = json['status'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'category': category,
+      'name': name,
+      'photoUrls': photoUrls,
+      'tags': tags,
+      'status': status
+    };
+  }
+
+  static List<Pet> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Pet>() : json.map((value) => new Pet.fromJson(value)).toList();
+  }
+
+  static Map<String, Pet> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Pet>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Pet.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/tag.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/tag.dart
new file mode 100644
index 00000000000..315a326adb7
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/tag.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Tag {
+  
+  int id = null;
+  
+  String name = null;
+  Tag();
+
+  @override
+  String toString() {
+    return 'Tag[id=$id, name=$name, ]';
+  }
+
+  Tag.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Tag> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Tag>() : json.map((value) => new Tag.fromJson(value)).toList();
+  }
+
+  static Map<String, Tag> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Tag>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Tag.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/user.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/user.dart
new file mode 100644
index 00000000000..0e4cc2104c7
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/user.dart
@@ -0,0 +1,64 @@
+part of openapi.api;
+
+class User {
+  
+  int id = null;
+  
+  String username = null;
+  
+  String firstName = null;
+  
+  String lastName = null;
+  
+  String email = null;
+  
+  String password = null;
+  
+  String phone = null;
+  /* User Status */
+  int userStatus = null;
+  User();
+
+  @override
+  String toString() {
+    return 'User[id=$id, username=$username, firstName=$firstName, lastName=$lastName, email=$email, password=$password, phone=$phone, userStatus=$userStatus, ]';
+  }
+
+  User.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    username = json['username'];
+    firstName = json['firstName'];
+    lastName = json['lastName'];
+    email = json['email'];
+    password = json['password'];
+    phone = json['phone'];
+    userStatus = json['userStatus'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'username': username,
+      'firstName': firstName,
+      'lastName': lastName,
+      'email': email,
+      'password': password,
+      'phone': phone,
+      'userStatus': userStatus
+    };
+  }
+
+  static List<User> listFromJson(List<dynamic> json) {
+    return json == null ? new List<User>() : json.map((value) => new User.fromJson(value)).toList();
+  }
+
+  static Map<String, User> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, User>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new User.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
new file mode 100644
index 00000000000..d54efb46a2e
--- /dev/null
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
@@ -0,0 +1,5 @@
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi-browser-client/.analysis_options b/samples/client/petstore/dart2/openapi-browser-client/.analysis_options
new file mode 100644
index 00000000000..518eb901a6f
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi-browser-client/.gitignore b/samples/client/petstore/dart2/openapi-browser-client/.gitignore
new file mode 100644
index 00000000000..7c280441649
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/.gitignore
@@ -0,0 +1,27 @@
+# See https://www.dartlang.org/tools/private-files.html
+
+# Files and directories created by pub
+.buildlog
+.packages
+.project
+.pub/
+build/
+**/packages/
+
+# Files created by dart2js
+# (Most Dart developers will use pub build to compile Dart, use/modify these 
+#  rules if you intend to use dart2js directly
+#  Convention is to use extension '.dart.js' for Dart compiled to Javascript to
+#  differentiate from explicit Javascript files)
+*.dart.js
+*.part.js
+*.js.deps
+*.js.map
+*.info.json
+
+# Directory created by dartdoc
+doc/api/
+
+# Don't commit pubspec lock file 
+# (Library packages only! Remove pattern if developing an application package)
+pubspec.lock
diff --git a/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator-ignore b/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator-ignore
new file mode 100644
index 00000000000..7484ee590a3
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator/VERSION b/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator/VERSION
new file mode 100644
index 00000000000..105bb87d77b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/.openapi-generator/VERSION
@@ -0,0 +1 @@
+3.2.2-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi-browser-client/README.md b/samples/client/petstore/dart2/openapi-browser-client/README.md
new file mode 100644
index 00000000000..5f3fe054784
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/README.md
@@ -0,0 +1,121 @@
+# openapi
+This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+
+This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: 1.0.0
+- Build package: org.openapitools.codegen.languages.DartClientCodegen
+
+## Requirements
+
+Dart 1.20.0 or later OR Flutter 0.0.20 or later
+
+## Installation & Usage
+
+### Github
+If this Dart package is published to Github, please include the following in pubspec.yaml
+```
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  openapi:
+    git: https://github.com/GIT_USER_ID/GIT_REPO_ID.git
+      version: 'any'
+```
+
+### Local
+To use the package in your local drive, please include the following in pubspec.yaml
+```
+dependencies:
+  openapi:
+    path: /path/to/openapi
+```
+
+## Tests
+
+TODO
+
+## Getting Started
+
+Please follow the [installation procedure](#installation--usage) and then run the following:
+
+```dart
+import 'package:openapi/api.dart';
+
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try {
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*PetApi* | [**addPet**](docs//PetApi.md#addpet) | **POST** /pet | Add a new pet to the store
+*PetApi* | [**deletePet**](docs//PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet
+*PetApi* | [**findPetsByStatus**](docs//PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status
+*PetApi* | [**findPetsByTags**](docs//PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags
+*PetApi* | [**getPetById**](docs//PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID
+*PetApi* | [**updatePet**](docs//PetApi.md#updatepet) | **PUT** /pet | Update an existing pet
+*PetApi* | [**updatePetWithForm**](docs//PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data
+*PetApi* | [**uploadFile**](docs//PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image
+*StoreApi* | [**deleteOrder**](docs//StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+*StoreApi* | [**getInventory**](docs//StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status
+*StoreApi* | [**getOrderById**](docs//StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID
+*StoreApi* | [**placeOrder**](docs//StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet
+*UserApi* | [**createUser**](docs//UserApi.md#createuser) | **POST** /user | Create user
+*UserApi* | [**createUsersWithArrayInput**](docs//UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array
+*UserApi* | [**createUsersWithListInput**](docs//UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array
+*UserApi* | [**deleteUser**](docs//UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user
+*UserApi* | [**getUserByName**](docs//UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name
+*UserApi* | [**loginUser**](docs//UserApi.md#loginuser) | **GET** /user/login | Logs user into the system
+*UserApi* | [**logoutUser**](docs//UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session
+*UserApi* | [**updateUser**](docs//UserApi.md#updateuser) | **PUT** /user/{username} | Updated user
+
+
+## Documentation For Models
+
+ - [ApiResponse](docs//ApiResponse.md)
+ - [Category](docs//Category.md)
+ - [Order](docs//Order.md)
+ - [Pet](docs//Pet.md)
+ - [Tag](docs//Tag.md)
+ - [User](docs//User.md)
+
+
+## Documentation For Authorization
+
+
+## api_key
+
+- **Type**: API key
+- **API key parameter name**: api_key
+- **Location**: HTTP header
+
+## petstore_auth
+
+- **Type**: OAuth
+- **Flow**: implicit
+- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
+- **Scopes**: 
+ - **write:pets**: modify pets in your account
+ - **read:pets**: read your pets
+
+
+## Author
+
+
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/ApiResponse.md b/samples/client/petstore/dart2/openapi-browser-client/docs/ApiResponse.md
new file mode 100644
index 00000000000..92422f0f446
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/ApiResponse.md
@@ -0,0 +1,17 @@
+# openapi.model.ApiResponse
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**code** | **int** |  | [optional] [default to null]
+**type** | **String** |  | [optional] [default to null]
+**message** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/Category.md b/samples/client/petstore/dart2/openapi-browser-client/docs/Category.md
new file mode 100644
index 00000000000..cc0d1633b59
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/Category.md
@@ -0,0 +1,16 @@
+# openapi.model.Category
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/Order.md b/samples/client/petstore/dart2/openapi-browser-client/docs/Order.md
new file mode 100644
index 00000000000..310ce6c65be
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/Order.md
@@ -0,0 +1,20 @@
+# openapi.model.Order
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**petId** | **int** |  | [optional] [default to null]
+**quantity** | **int** |  | [optional] [default to null]
+**shipDate** | [**DateTime**](DateTime.md) |  | [optional] [default to null]
+**status** | **String** | Order Status | [optional] [default to null]
+**complete** | **bool** |  | [optional] [default to false]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/Pet.md b/samples/client/petstore/dart2/openapi-browser-client/docs/Pet.md
new file mode 100644
index 00000000000..191e1fc66a9
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/Pet.md
@@ -0,0 +1,20 @@
+# openapi.model.Pet
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**category** | [**Category**](Category.md) |  | [optional] [default to null]
+**name** | **String** |  | [default to null]
+**photoUrls** | **List&lt;String&gt;** |  | [default to []]
+**tags** | [**List&lt;Tag&gt;**](Tag.md) |  | [optional] [default to []]
+**status** | **String** | pet status in the store | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/PetApi.md b/samples/client/petstore/dart2/openapi-browser-client/docs/PetApi.md
new file mode 100644
index 00000000000..6fa9abf67ae
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/PetApi.md
@@ -0,0 +1,379 @@
+# openapi.api.PetApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**addPet**](PetApi.md#addPet) | **POST** /pet | Add a new pet to the store
+[**deletePet**](PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet
+[**findPetsByStatus**](PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
+[**findPetsByTags**](PetApi.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags
+[**getPetById**](PetApi.md#getPetById) | **GET** /pet/{petId} | Find pet by ID
+[**updatePet**](PetApi.md#updatePet) | **PUT** /pet | Update an existing pet
+[**updatePetWithForm**](PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data
+[**uploadFile**](PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image
+
+
+# **addPet**
+> addPet(pet)
+
+Add a new pet to the store
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deletePet**
+> deletePet(petId, apiKey)
+
+Deletes a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | Pet id to delete
+var apiKey = apiKey_example; // String | 
+
+try { 
+    api_instance.deletePet(petId, apiKey);
+} catch (e) {
+    print("Exception when calling PetApi->deletePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| Pet id to delete | 
+ **apiKey** | **String**|  | [optional] 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByStatus**
+> List<Pet> findPetsByStatus(status)
+
+Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var status = []; // List<String> | Status values that need to be considered for filter
+
+try { 
+    var result = api_instance.findPetsByStatus(status);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByStatus: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **status** | [**List&lt;String&gt;**](String.md)| Status values that need to be considered for filter | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByTags**
+> List<Pet> findPetsByTags(tags)
+
+Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var tags = []; // List<String> | Tags to filter by
+
+try { 
+    var result = api_instance.findPetsByTags(tags);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByTags: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **tags** | [**List&lt;String&gt;**](String.md)| Tags to filter by | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getPetById**
+> Pet getPetById(petId)
+
+Find pet by ID
+
+Returns a single pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to return
+
+try { 
+    var result = api_instance.getPetById(petId);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->getPetById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to return | 
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePet**
+> updatePet(pet)
+
+Update an existing pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.updatePet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->updatePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePetWithForm**
+> updatePetWithForm(petId, name, status)
+
+Updates a pet in the store with form data
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet that needs to be updated
+var name = name_example; // String | Updated name of the pet
+var status = status_example; // String | Updated status of the pet
+
+try { 
+    api_instance.updatePetWithForm(petId, name, status);
+} catch (e) {
+    print("Exception when calling PetApi->updatePetWithForm: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet that needs to be updated | 
+ **name** | **String**| Updated name of the pet | [optional] [default to null]
+ **status** | **String**| Updated status of the pet | [optional] [default to null]
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/x-www-form-urlencoded
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **uploadFile**
+> ApiResponse uploadFile(petId, additionalMetadata, file)
+
+uploads an image
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to update
+var additionalMetadata = additionalMetadata_example; // String | Additional data to pass to server
+var file = BINARY_DATA_HERE; // MultipartFile | file to upload
+
+try { 
+    var result = api_instance.uploadFile(petId, additionalMetadata, file);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->uploadFile: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to update | 
+ **additionalMetadata** | **String**| Additional data to pass to server | [optional] [default to null]
+ **file** | **MultipartFile**| file to upload | [optional] [default to null]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/StoreApi.md b/samples/client/petstore/dart2/openapi-browser-client/docs/StoreApi.md
new file mode 100644
index 00000000000..cc0c2ac2d35
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/StoreApi.md
@@ -0,0 +1,186 @@
+# openapi.api.StoreApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**deleteOrder**](StoreApi.md#deleteOrder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+[**getInventory**](StoreApi.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status
+[**getOrderById**](StoreApi.md#getOrderById) | **GET** /store/order/{orderId} | Find purchase order by ID
+[**placeOrder**](StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet
+
+
+# **deleteOrder**
+> deleteOrder(orderId)
+
+Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = orderId_example; // String | ID of the order that needs to be deleted
+
+try { 
+    api_instance.deleteOrder(orderId);
+} catch (e) {
+    print("Exception when calling StoreApi->deleteOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **String**| ID of the order that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getInventory**
+> Map<String, int> getInventory()
+
+Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new StoreApi();
+
+try { 
+    var result = api_instance.getInventory();
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getInventory: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+**Map<String, int>**
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getOrderById**
+> Order getOrderById(orderId)
+
+Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = 789; // int | ID of pet that needs to be fetched
+
+try { 
+    var result = api_instance.getOrderById(orderId);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getOrderById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **int**| ID of pet that needs to be fetched | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **placeOrder**
+> Order placeOrder(order)
+
+Place an order for a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var order = new Order(); // Order | order placed for purchasing the pet
+
+try { 
+    var result = api_instance.placeOrder(order);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->placeOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **order** | [**Order**](Order.md)| order placed for purchasing the pet | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/Tag.md b/samples/client/petstore/dart2/openapi-browser-client/docs/Tag.md
new file mode 100644
index 00000000000..ded7b32ac3d
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/Tag.md
@@ -0,0 +1,16 @@
+# openapi.model.Tag
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/User.md b/samples/client/petstore/dart2/openapi-browser-client/docs/User.md
new file mode 100644
index 00000000000..3761b70cf0b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/User.md
@@ -0,0 +1,22 @@
+# openapi.model.User
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**username** | **String** |  | [optional] [default to null]
+**firstName** | **String** |  | [optional] [default to null]
+**lastName** | **String** |  | [optional] [default to null]
+**email** | **String** |  | [optional] [default to null]
+**password** | **String** |  | [optional] [default to null]
+**phone** | **String** |  | [optional] [default to null]
+**userStatus** | **int** | User Status | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/docs/UserApi.md b/samples/client/petstore/dart2/openapi-browser-client/docs/UserApi.md
new file mode 100644
index 00000000000..0dec271be5c
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/docs/UserApi.md
@@ -0,0 +1,349 @@
+# openapi.api.UserApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**createUser**](UserApi.md#createUser) | **POST** /user | Create user
+[**createUsersWithArrayInput**](UserApi.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array
+[**createUsersWithListInput**](UserApi.md#createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array
+[**deleteUser**](UserApi.md#deleteUser) | **DELETE** /user/{username} | Delete user
+[**getUserByName**](UserApi.md#getUserByName) | **GET** /user/{username} | Get user by user name
+[**loginUser**](UserApi.md#loginUser) | **GET** /user/login | Logs user into the system
+[**logoutUser**](UserApi.md#logoutUser) | **GET** /user/logout | Logs out current logged in user session
+[**updateUser**](UserApi.md#updateUser) | **PUT** /user/{username} | Updated user
+
+
+# **createUser**
+> createUser(user)
+
+Create user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = new User(); // User | Created user object
+
+try { 
+    api_instance.createUser(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**User**](User.md)| Created user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithArrayInput**
+> createUsersWithArrayInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithArrayInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithArrayInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithListInput**
+> createUsersWithListInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithListInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithListInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deleteUser**
+> deleteUser(username)
+
+Delete user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be deleted
+
+try { 
+    api_instance.deleteUser(username);
+} catch (e) {
+    print("Exception when calling UserApi->deleteUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getUserByName**
+> User getUserByName(username)
+
+Get user by user name
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be fetched. Use user1 for testing.
+
+try { 
+    var result = api_instance.getUserByName(username);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->getUserByName: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be fetched. Use user1 for testing. | 
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **loginUser**
+> String loginUser(username, password)
+
+Logs user into the system
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The user name for login
+var password = password_example; // String | The password for login in clear text
+
+try { 
+    var result = api_instance.loginUser(username, password);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->loginUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The user name for login | 
+ **password** | **String**| The password for login in clear text | 
+
+### Return type
+
+**String**
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **logoutUser**
+> logoutUser()
+
+Logs out current logged in user session
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+
+try { 
+    api_instance.logoutUser();
+} catch (e) {
+    print("Exception when calling UserApi->logoutUser: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updateUser**
+> updateUser(username, user)
+
+Updated user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | name that need to be deleted
+var user = new User(); // User | Updated user object
+
+try { 
+    api_instance.updateUser(username, user);
+} catch (e) {
+    print("Exception when calling UserApi->updateUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| name that need to be deleted | 
+ **user** | [**User**](User.md)| Updated user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/git_push.sh b/samples/client/petstore/dart2/openapi-browser-client/git_push.sh
new file mode 100644
index 00000000000..8442b80bb44
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/git_push.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+
+if [ "$git_user_id" = "" ]; then
+    git_user_id="GIT_USER_ID"
+    echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+    git_repo_id="GIT_REPO_ID"
+    echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+    release_note="Minor update"
+    echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository. 
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=`git remote`
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+    if [ "$GIT_TOKEN" = "" ]; then
+        echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+        git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
+    else
+        git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
+    fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
new file mode 100644
index 00000000000..84476e0626a
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
@@ -0,0 +1,28 @@
+library openapi.api;
+
+import 'dart:async';
+import 'dart:convert';
+import 'package:http/browser_client.dart';
+import 'package:http/http.dart';
+
+part 'api_client.dart';
+part 'api_helper.dart';
+part 'api_exception.dart';
+part 'auth/authentication.dart';
+part 'auth/api_key_auth.dart';
+part 'auth/oauth.dart';
+part 'auth/http_basic_auth.dart';
+
+part 'api/pet_api.dart';
+part 'api/store_api.dart';
+part 'api/user_api.dart';
+
+part 'model/api_response.dart';
+part 'model/category.dart';
+part 'model/order.dart';
+part 'model/pet.dart';
+part 'model/tag.dart';
+part 'model/user.dart';
+
+
+ApiClient defaultApiClient = new ApiClient();
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
new file mode 100644
index 00000000000..4134e018386
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
@@ -0,0 +1,432 @@
+part of openapi.api;
+
+
+
+class PetApi {
+  final ApiClient apiClient;
+
+  PetApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Add a new pet to the store
+  ///
+  /// 
+  Future addPet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Deletes a pet
+  ///
+  /// 
+  Future deletePet(int petId, { String apiKey }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+    headerParams["api_key"] = apiKey;
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Finds Pets by status
+  ///
+  /// Multiple status values can be provided with comma separated strings
+  Future<List<Pet>> findPetsByStatus(List<String> status) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(status == null) {
+     throw new ApiException(400, "Missing required param: status");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByStatus".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "status", status));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Finds Pets by tags
+  ///
+  /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+  Future<List<Pet>> findPetsByTags(List<String> tags) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(tags == null) {
+     throw new ApiException(400, "Missing required param: tags");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByTags".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "tags", tags));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Find pet by ID
+  ///
+  /// Returns a single pet
+  Future<Pet> getPetById(int petId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Pet') as Pet;
+    } else {
+      return null;
+    }
+  }
+  /// Update an existing pet
+  ///
+  /// 
+  Future updatePet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updates a pet in the store with form data
+  ///
+  /// 
+  Future updatePetWithForm(int petId, { String name, String status }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/x-www-form-urlencoded"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (name != null) {
+        hasFields = true;
+        mp.fields['name'] = parameterToString(name);
+      }
+      if (status != null) {
+        hasFields = true;
+        mp.fields['status'] = parameterToString(status);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (name != null)
+        formParams['name'] = parameterToString(name);
+      if (status != null)
+        formParams['status'] = parameterToString(status);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// uploads an image
+  ///
+  /// 
+  Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}/uploadImage".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["multipart/form-data"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (additionalMetadata != null) {
+        hasFields = true;
+        mp.fields['additionalMetadata'] = parameterToString(additionalMetadata);
+      }
+      if (file != null) {
+        hasFields = true;
+        mp.fields['file'] = file.field;
+        mp.files.add(file);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (additionalMetadata != null)
+        formParams['additionalMetadata'] = parameterToString(additionalMetadata);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'ApiResponse') as ApiResponse;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
new file mode 100644
index 00000000000..f2a48f2d4da
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
@@ -0,0 +1,207 @@
+part of openapi.api;
+
+
+
+class StoreApi {
+  final ApiClient apiClient;
+
+  StoreApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Delete purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
+  Future deleteOrder(String orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Returns pet inventories by status
+  ///
+  /// Returns a map of status codes to quantities
+  Future<Map<String, int>> getInventory() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/store/inventory".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return new Map<String, int>.from(apiClient.deserialize(response.body, 'Map<String, int>'));
+          ;
+    } else {
+      return null;
+    }
+  }
+  /// Find purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
+  Future<Order> getOrderById(int orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+  /// Place an order for a pet
+  ///
+  /// 
+  Future<Order> placeOrder(Order order) async {
+    Object postBody = order;
+
+    // verify required params are set
+    if(order == null) {
+     throw new ApiException(400, "Missing required param: order");
+    }
+
+    // create path and map variables
+    String path = "/store/order".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
new file mode 100644
index 00000000000..cf8ef6bf800
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
@@ -0,0 +1,409 @@
+part of openapi.api;
+
+
+
+class UserApi {
+  final ApiClient apiClient;
+
+  UserApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Create user
+  ///
+  /// This can only be done by the logged in user.
+  Future createUser(User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithArrayInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithArray".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithListInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithList".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Delete user
+  ///
+  /// This can only be done by the logged in user.
+  Future deleteUser(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Get user by user name
+  ///
+  /// 
+  Future<User> getUserByName(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'User') as User;
+    } else {
+      return null;
+    }
+  }
+  /// Logs user into the system
+  ///
+  /// 
+  Future<String> loginUser(String username, String password) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(password == null) {
+     throw new ApiException(400, "Missing required param: password");
+    }
+
+    // create path and map variables
+    String path = "/user/login".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("", "username", username));
+      queryParams.addAll(_convertParametersForCollectionFormat("", "password", password));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'String') as String;
+    } else {
+      return null;
+    }
+  }
+  /// Logs out current logged in user session
+  ///
+  /// 
+  Future logoutUser() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/user/logout".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updated user
+  ///
+  /// This can only be done by the logged in user.
+  Future updateUser(String username, User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
new file mode 100644
index 00000000000..7cca5bef5f2
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
@@ -0,0 +1,160 @@
+part of openapi.api;
+
+class QueryParam {
+  String name;
+  String value;
+
+  QueryParam(this.name, this.value);
+}
+
+class ApiClient {
+
+  String basePath;
+  var client = new BrowserClient();
+
+  Map<String, String> _defaultHeaderMap = {};
+  Map<String, Authentication> _authentications = {};
+
+  final _RegList = new RegExp(r'^List<(.*)>$');
+  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+
+  ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
+    // Setup authentications (key: authentication name, value: authentication).
+    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = new OAuth();
+  }
+
+  void addDefaultHeader(String key, String value) {
+     _defaultHeaderMap[key] = value;
+  }
+
+  dynamic _deserialize(dynamic value, String targetType) {
+    try {
+      switch (targetType) {
+        case 'String':
+          return '$value';
+        case 'int':
+          return value is int ? value : int.parse('$value');
+        case 'bool':
+          return value is bool ? value : '$value'.toLowerCase() == 'true';
+        case 'double':
+          return value is double ? value : double.parse('$value');
+        case 'ApiResponse':
+          return new ApiResponse.fromJson(value);
+        case 'Category':
+          return new Category.fromJson(value);
+        case 'Order':
+          return new Order.fromJson(value);
+        case 'Pet':
+          return new Pet.fromJson(value);
+        case 'Tag':
+          return new Tag.fromJson(value);
+        case 'User':
+          return new User.fromJson(value);
+        default:
+          {
+            Match match;
+            if (value is List &&
+                (match = _RegList.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return value.map((v) => _deserialize(v, newTargetType)).toList();
+            } else if (value is Map &&
+                (match = _RegMap.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return new Map.fromIterables(value.keys,
+                  value.values.map((v) => _deserialize(v, newTargetType)));
+            }
+          }
+      }
+    } catch (e, stack) {
+      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+    }
+    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+  }
+
+  dynamic deserialize(String json, String targetType) {
+    // Remove all spaces.  Necessary for reg expressions as well.
+    targetType = targetType.replaceAll(' ', '');
+
+    if (targetType == 'String') return json;
+
+    var decodedJson = JSON.decode(json);
+    return _deserialize(decodedJson, targetType);
+  }
+
+  String serialize(Object obj) {
+    String serialized = '';
+    if (obj == null) {
+      serialized = '';
+    } else {
+      serialized = JSON.encode(obj);
+    }
+    return serialized;
+  }
+
+  // We don't use a Map<String, String> for queryParams.
+  // If collectionFormat is 'multi' a key might appear multiple times.
+  Future<Response> invokeAPI(String path,
+                             String method,
+                             Iterable<QueryParam> queryParams,
+                             Object body,
+                             Map<String, String> headerParams,
+                             Map<String, String> formParams,
+                             String contentType,
+                             List<String> authNames) async {
+
+    _updateParamsForAuth(authNames, queryParams, headerParams);
+
+    var ps = queryParams.where((p) => p.value != null).map((p) => '${p.name}=${p.value}');
+    String queryString = ps.isNotEmpty ?
+                         '?' + ps.join('&') :
+                         '';
+
+    String url = basePath + path + queryString;
+
+    headerParams.addAll(_defaultHeaderMap);
+    headerParams['Content-Type'] = contentType;
+
+    if(body is MultipartRequest) {
+      var request = new MultipartRequest(method, Uri.parse(url));
+      request.fields.addAll(body.fields);
+      request.files.addAll(body.files);
+      request.headers.addAll(body.headers);
+      request.headers.addAll(headerParams);
+      var response = await client.send(request);
+      return Response.fromStream(response);
+    } else {
+      var msgBody = contentType == "application/x-www-form-urlencoded" ? formParams : serialize(body);
+      switch(method) {
+        case "POST":
+          return client.post(url, headers: headerParams, body: msgBody);
+        case "PUT":
+          return client.put(url, headers: headerParams, body: msgBody);
+        case "DELETE":
+          return client.delete(url, headers: headerParams);
+        case "PATCH":
+          return client.patch(url, headers: headerParams, body: msgBody);
+        default:
+          return client.get(url, headers: headerParams);
+      }
+    }
+  }
+
+  /// Update query and header parameters based on authentication settings.
+  /// @param authNames The authentications to apply
+  void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
+    authNames.forEach((authName) {
+      Authentication auth = _authentications[authName];
+      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      auth.applyToParams(queryParams, headerParams);
+    });
+  }
+
+  void setAccessToken(String accessToken) {
+    _authentications.forEach((key, auth) {
+      if (auth is OAuth) {
+        auth.setAccessToken(accessToken);
+      }
+    });
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
new file mode 100644
index 00000000000..f188fd125a4
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
@@ -0,0 +1,23 @@
+part of openapi.api;
+
+class ApiException implements Exception {
+  int code = 0;
+  String message = null;
+  Exception innerException = null;
+  StackTrace stackTrace = null;
+
+  ApiException(this.code, this.message);
+
+  ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace);
+
+  String toString() {
+    if (message == null) return "ApiException";
+
+    if (innerException == null) {
+      return "ApiException $code: $message";
+    }
+
+    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+        stackTrace.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
new file mode 100644
index 00000000000..79af4521d5b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+const _delimiters = const {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
+
+// port from Java version
+Iterable<QueryParam> _convertParametersForCollectionFormat(
+  String collectionFormat, String name, dynamic value) {
+  var params = <QueryParam>[];
+
+  // preconditions
+  if (name == null || name.isEmpty || value == null) return params;
+
+  if (value is! List) {
+    params.add(new QueryParam(name, parameterToString(value)));
+    return params;
+  }
+
+  List values = value as List;
+
+  // get the collection format
+  collectionFormat = (collectionFormat == null || collectionFormat.isEmpty)
+                     ? "csv"
+                     : collectionFormat; // default: csv
+
+  if (collectionFormat == "multi") {
+    return values.map((v) => new QueryParam(name, parameterToString(v)));
+  }
+
+  String delimiter = _delimiters[collectionFormat] ?? ",";
+
+  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  return params;
+}
+
+/// Format the given parameter object into string.
+String parameterToString(dynamic value) {
+  if (value == null) {
+    return '';
+  } else if (value is DateTime) {
+    return value.toUtc().toIso8601String();
+  } else {
+    return value.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
new file mode 100644
index 00000000000..f9617f7ae4d
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
@@ -0,0 +1,27 @@
+part of openapi.api;
+
+class ApiKeyAuth implements Authentication {
+
+  final String location;
+  final String paramName;
+  String apiKey;
+  String apiKeyPrefix;
+
+  ApiKeyAuth(this.location, this.paramName);
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String value;
+    if (apiKeyPrefix != null) {
+      value = '$apiKeyPrefix $apiKey';
+    } else {
+      value = apiKey;
+    }
+
+    if (location == 'query' && value != null) {
+      queryParams.add(new QueryParam(paramName, value));
+    } else if (location == 'header' && value != null) {
+      headerParams[paramName] = value;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/authentication.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/authentication.dart
new file mode 100644
index 00000000000..abd5e2fe68a
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/authentication.dart
@@ -0,0 +1,7 @@
+part of openapi.api;
+
+abstract class Authentication {
+
+	/// Apply authentication settings to header and query params.
+	void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams);
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
new file mode 100644
index 00000000000..4e77ddcf6e6
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
@@ -0,0 +1,14 @@
+part of openapi.api;
+
+class HttpBasicAuth implements Authentication {
+
+  String username;
+  String password;
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
+    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+  }
+
+}
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
new file mode 100644
index 00000000000..13bfd799743
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
@@ -0,0 +1,19 @@
+part of openapi.api;
+
+class OAuth implements Authentication {
+  String accessToken;
+
+  OAuth({this.accessToken}) {
+  }
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    if (accessToken != null) {
+      headerParams["Authorization"] = "Bearer " + accessToken;
+    }
+  }
+
+  void setAccessToken(String accessToken) {
+    this.accessToken = accessToken;
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/api_response.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/api_response.dart
new file mode 100644
index 00000000000..a39d9500b29
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/api_response.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+class ApiResponse {
+  
+  int code = null;
+  
+  String type = null;
+  
+  String message = null;
+  ApiResponse();
+
+  @override
+  String toString() {
+    return 'ApiResponse[code=$code, type=$type, message=$message, ]';
+  }
+
+  ApiResponse.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    code = json['code'];
+    type = json['type'];
+    message = json['message'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'code': code,
+      'type': type,
+      'message': message
+    };
+  }
+
+  static List<ApiResponse> listFromJson(List<dynamic> json) {
+    return json == null ? new List<ApiResponse>() : json.map((value) => new ApiResponse.fromJson(value)).toList();
+  }
+
+  static Map<String, ApiResponse> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, ApiResponse>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new ApiResponse.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/category.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/category.dart
new file mode 100644
index 00000000000..b9b2481dd29
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/category.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Category {
+  
+  int id = null;
+  
+  String name = null;
+  Category();
+
+  @override
+  String toString() {
+    return 'Category[id=$id, name=$name, ]';
+  }
+
+  Category.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Category> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Category>() : json.map((value) => new Category.fromJson(value)).toList();
+  }
+
+  static Map<String, Category> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Category>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Category.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/order.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/order.dart
new file mode 100644
index 00000000000..4e264a183ef
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/order.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Order {
+  
+  int id = null;
+  
+  int petId = null;
+  
+  int quantity = null;
+  
+  DateTime shipDate = null;
+  /* Order Status */
+  String status = null;
+  //enum statusEnum {  placed,  approved,  delivered,  };{
+  
+  bool complete = false;
+  Order();
+
+  @override
+  String toString() {
+    return 'Order[id=$id, petId=$petId, quantity=$quantity, shipDate=$shipDate, status=$status, complete=$complete, ]';
+  }
+
+  Order.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    petId = json['petId'];
+    quantity = json['quantity'];
+    shipDate = json['shipDate'] == null ? null : DateTime.parse(json['shipDate']);
+    status = json['status'];
+    complete = json['complete'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'petId': petId,
+      'quantity': quantity,
+      'shipDate': shipDate == null ? '' : shipDate.toUtc().toIso8601String(),
+      'status': status,
+      'complete': complete
+    };
+  }
+
+  static List<Order> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Order>() : json.map((value) => new Order.fromJson(value)).toList();
+  }
+
+  static Map<String, Order> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Order>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Order.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
new file mode 100644
index 00000000000..4d2f77a1a5a
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Pet {
+  
+  int id = null;
+  
+  Category category = null;
+  
+  String name = null;
+  
+  List<String> photoUrls = [];
+  
+  List<Tag> tags = [];
+  /* pet status in the store */
+  String status = null;
+  //enum statusEnum {  available,  pending,  sold,  };{
+  Pet();
+
+  @override
+  String toString() {
+    return 'Pet[id=$id, category=$category, name=$name, photoUrls=$photoUrls, tags=$tags, status=$status, ]';
+  }
+
+  Pet.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    category = new Category.fromJson(json['category']);
+    name = json['name'];
+    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    tags = Tag.listFromJson(json['tags']);
+    status = json['status'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'category': category,
+      'name': name,
+      'photoUrls': photoUrls,
+      'tags': tags,
+      'status': status
+    };
+  }
+
+  static List<Pet> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Pet>() : json.map((value) => new Pet.fromJson(value)).toList();
+  }
+
+  static Map<String, Pet> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Pet>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Pet.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/tag.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/tag.dart
new file mode 100644
index 00000000000..315a326adb7
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/tag.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Tag {
+  
+  int id = null;
+  
+  String name = null;
+  Tag();
+
+  @override
+  String toString() {
+    return 'Tag[id=$id, name=$name, ]';
+  }
+
+  Tag.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Tag> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Tag>() : json.map((value) => new Tag.fromJson(value)).toList();
+  }
+
+  static Map<String, Tag> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Tag>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Tag.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/user.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/user.dart
new file mode 100644
index 00000000000..0e4cc2104c7
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/user.dart
@@ -0,0 +1,64 @@
+part of openapi.api;
+
+class User {
+  
+  int id = null;
+  
+  String username = null;
+  
+  String firstName = null;
+  
+  String lastName = null;
+  
+  String email = null;
+  
+  String password = null;
+  
+  String phone = null;
+  /* User Status */
+  int userStatus = null;
+  User();
+
+  @override
+  String toString() {
+    return 'User[id=$id, username=$username, firstName=$firstName, lastName=$lastName, email=$email, password=$password, phone=$phone, userStatus=$userStatus, ]';
+  }
+
+  User.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    username = json['username'];
+    firstName = json['firstName'];
+    lastName = json['lastName'];
+    email = json['email'];
+    password = json['password'];
+    phone = json['phone'];
+    userStatus = json['userStatus'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'username': username,
+      'firstName': firstName,
+      'lastName': lastName,
+      'email': email,
+      'password': password,
+      'phone': phone,
+      'userStatus': userStatus
+    };
+  }
+
+  static List<User> listFromJson(List<dynamic> json) {
+    return json == null ? new List<User>() : json.map((value) => new User.fromJson(value)).toList();
+  }
+
+  static Map<String, User> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, User>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new User.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
new file mode 100644
index 00000000000..d54efb46a2e
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
@@ -0,0 +1,5 @@
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi/.analysis_options b/samples/client/petstore/dart2/openapi/.analysis_options
new file mode 100644
index 00000000000..518eb901a6f
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi/.gitignore b/samples/client/petstore/dart2/openapi/.gitignore
new file mode 100644
index 00000000000..7c280441649
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/.gitignore
@@ -0,0 +1,27 @@
+# See https://www.dartlang.org/tools/private-files.html
+
+# Files and directories created by pub
+.buildlog
+.packages
+.project
+.pub/
+build/
+**/packages/
+
+# Files created by dart2js
+# (Most Dart developers will use pub build to compile Dart, use/modify these 
+#  rules if you intend to use dart2js directly
+#  Convention is to use extension '.dart.js' for Dart compiled to Javascript to
+#  differentiate from explicit Javascript files)
+*.dart.js
+*.part.js
+*.js.deps
+*.js.map
+*.info.json
+
+# Directory created by dartdoc
+doc/api/
+
+# Don't commit pubspec lock file 
+# (Library packages only! Remove pattern if developing an application package)
+pubspec.lock
diff --git a/samples/client/petstore/dart2/openapi/.openapi-generator-ignore b/samples/client/petstore/dart2/openapi/.openapi-generator-ignore
new file mode 100644
index 00000000000..7484ee590a3
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/.openapi-generator-ignore
@@ -0,0 +1,23 @@
+# OpenAPI Generator Ignore
+# Generated by openapi-generator https://github.com/openapitools/openapi-generator
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION b/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION
new file mode 100644
index 00000000000..105bb87d77b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/.openapi-generator/VERSION
@@ -0,0 +1 @@
+3.2.2-SNAPSHOT
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi/README.md b/samples/client/petstore/dart2/openapi/README.md
new file mode 100644
index 00000000000..5f3fe054784
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/README.md
@@ -0,0 +1,121 @@
+# openapi
+This is a sample server Petstore server. For this sample, you can use the api key `special-key` to test the authorization filters.
+
+This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project:
+
+- API version: 1.0.0
+- Build package: org.openapitools.codegen.languages.DartClientCodegen
+
+## Requirements
+
+Dart 1.20.0 or later OR Flutter 0.0.20 or later
+
+## Installation & Usage
+
+### Github
+If this Dart package is published to Github, please include the following in pubspec.yaml
+```
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  openapi:
+    git: https://github.com/GIT_USER_ID/GIT_REPO_ID.git
+      version: 'any'
+```
+
+### Local
+To use the package in your local drive, please include the following in pubspec.yaml
+```
+dependencies:
+  openapi:
+    path: /path/to/openapi
+```
+
+## Tests
+
+TODO
+
+## Getting Started
+
+Please follow the [installation procedure](#installation--usage) and then run the following:
+
+```dart
+import 'package:openapi/api.dart';
+
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try {
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*PetApi* | [**addPet**](docs//PetApi.md#addpet) | **POST** /pet | Add a new pet to the store
+*PetApi* | [**deletePet**](docs//PetApi.md#deletepet) | **DELETE** /pet/{petId} | Deletes a pet
+*PetApi* | [**findPetsByStatus**](docs//PetApi.md#findpetsbystatus) | **GET** /pet/findByStatus | Finds Pets by status
+*PetApi* | [**findPetsByTags**](docs//PetApi.md#findpetsbytags) | **GET** /pet/findByTags | Finds Pets by tags
+*PetApi* | [**getPetById**](docs//PetApi.md#getpetbyid) | **GET** /pet/{petId} | Find pet by ID
+*PetApi* | [**updatePet**](docs//PetApi.md#updatepet) | **PUT** /pet | Update an existing pet
+*PetApi* | [**updatePetWithForm**](docs//PetApi.md#updatepetwithform) | **POST** /pet/{petId} | Updates a pet in the store with form data
+*PetApi* | [**uploadFile**](docs//PetApi.md#uploadfile) | **POST** /pet/{petId}/uploadImage | uploads an image
+*StoreApi* | [**deleteOrder**](docs//StoreApi.md#deleteorder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+*StoreApi* | [**getInventory**](docs//StoreApi.md#getinventory) | **GET** /store/inventory | Returns pet inventories by status
+*StoreApi* | [**getOrderById**](docs//StoreApi.md#getorderbyid) | **GET** /store/order/{orderId} | Find purchase order by ID
+*StoreApi* | [**placeOrder**](docs//StoreApi.md#placeorder) | **POST** /store/order | Place an order for a pet
+*UserApi* | [**createUser**](docs//UserApi.md#createuser) | **POST** /user | Create user
+*UserApi* | [**createUsersWithArrayInput**](docs//UserApi.md#createuserswitharrayinput) | **POST** /user/createWithArray | Creates list of users with given input array
+*UserApi* | [**createUsersWithListInput**](docs//UserApi.md#createuserswithlistinput) | **POST** /user/createWithList | Creates list of users with given input array
+*UserApi* | [**deleteUser**](docs//UserApi.md#deleteuser) | **DELETE** /user/{username} | Delete user
+*UserApi* | [**getUserByName**](docs//UserApi.md#getuserbyname) | **GET** /user/{username} | Get user by user name
+*UserApi* | [**loginUser**](docs//UserApi.md#loginuser) | **GET** /user/login | Logs user into the system
+*UserApi* | [**logoutUser**](docs//UserApi.md#logoutuser) | **GET** /user/logout | Logs out current logged in user session
+*UserApi* | [**updateUser**](docs//UserApi.md#updateuser) | **PUT** /user/{username} | Updated user
+
+
+## Documentation For Models
+
+ - [ApiResponse](docs//ApiResponse.md)
+ - [Category](docs//Category.md)
+ - [Order](docs//Order.md)
+ - [Pet](docs//Pet.md)
+ - [Tag](docs//Tag.md)
+ - [User](docs//User.md)
+
+
+## Documentation For Authorization
+
+
+## api_key
+
+- **Type**: API key
+- **API key parameter name**: api_key
+- **Location**: HTTP header
+
+## petstore_auth
+
+- **Type**: OAuth
+- **Flow**: implicit
+- **Authorization URL**: http://petstore.swagger.io/api/oauth/dialog
+- **Scopes**: 
+ - **write:pets**: modify pets in your account
+ - **read:pets**: read your pets
+
+
+## Author
+
+
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/ApiResponse.md b/samples/client/petstore/dart2/openapi/docs/ApiResponse.md
new file mode 100644
index 00000000000..92422f0f446
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/ApiResponse.md
@@ -0,0 +1,17 @@
+# openapi.model.ApiResponse
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**code** | **int** |  | [optional] [default to null]
+**type** | **String** |  | [optional] [default to null]
+**message** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/Category.md b/samples/client/petstore/dart2/openapi/docs/Category.md
new file mode 100644
index 00000000000..cc0d1633b59
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/Category.md
@@ -0,0 +1,16 @@
+# openapi.model.Category
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/Order.md b/samples/client/petstore/dart2/openapi/docs/Order.md
new file mode 100644
index 00000000000..310ce6c65be
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/Order.md
@@ -0,0 +1,20 @@
+# openapi.model.Order
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**petId** | **int** |  | [optional] [default to null]
+**quantity** | **int** |  | [optional] [default to null]
+**shipDate** | [**DateTime**](DateTime.md) |  | [optional] [default to null]
+**status** | **String** | Order Status | [optional] [default to null]
+**complete** | **bool** |  | [optional] [default to false]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/Pet.md b/samples/client/petstore/dart2/openapi/docs/Pet.md
new file mode 100644
index 00000000000..191e1fc66a9
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/Pet.md
@@ -0,0 +1,20 @@
+# openapi.model.Pet
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**category** | [**Category**](Category.md) |  | [optional] [default to null]
+**name** | **String** |  | [default to null]
+**photoUrls** | **List&lt;String&gt;** |  | [default to []]
+**tags** | [**List&lt;Tag&gt;**](Tag.md) |  | [optional] [default to []]
+**status** | **String** | pet status in the store | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/PetApi.md b/samples/client/petstore/dart2/openapi/docs/PetApi.md
new file mode 100644
index 00000000000..6fa9abf67ae
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/PetApi.md
@@ -0,0 +1,379 @@
+# openapi.api.PetApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**addPet**](PetApi.md#addPet) | **POST** /pet | Add a new pet to the store
+[**deletePet**](PetApi.md#deletePet) | **DELETE** /pet/{petId} | Deletes a pet
+[**findPetsByStatus**](PetApi.md#findPetsByStatus) | **GET** /pet/findByStatus | Finds Pets by status
+[**findPetsByTags**](PetApi.md#findPetsByTags) | **GET** /pet/findByTags | Finds Pets by tags
+[**getPetById**](PetApi.md#getPetById) | **GET** /pet/{petId} | Find pet by ID
+[**updatePet**](PetApi.md#updatePet) | **PUT** /pet | Update an existing pet
+[**updatePetWithForm**](PetApi.md#updatePetWithForm) | **POST** /pet/{petId} | Updates a pet in the store with form data
+[**uploadFile**](PetApi.md#uploadFile) | **POST** /pet/{petId}/uploadImage | uploads an image
+
+
+# **addPet**
+> addPet(pet)
+
+Add a new pet to the store
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.addPet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->addPet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deletePet**
+> deletePet(petId, apiKey)
+
+Deletes a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | Pet id to delete
+var apiKey = apiKey_example; // String | 
+
+try { 
+    api_instance.deletePet(petId, apiKey);
+} catch (e) {
+    print("Exception when calling PetApi->deletePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| Pet id to delete | 
+ **apiKey** | **String**|  | [optional] 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByStatus**
+> List<Pet> findPetsByStatus(status)
+
+Finds Pets by status
+
+Multiple status values can be provided with comma separated strings
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var status = []; // List<String> | Status values that need to be considered for filter
+
+try { 
+    var result = api_instance.findPetsByStatus(status);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByStatus: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **status** | [**List&lt;String&gt;**](String.md)| Status values that need to be considered for filter | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **findPetsByTags**
+> List<Pet> findPetsByTags(tags)
+
+Finds Pets by tags
+
+Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var tags = []; // List<String> | Tags to filter by
+
+try { 
+    var result = api_instance.findPetsByTags(tags);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->findPetsByTags: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **tags** | [**List&lt;String&gt;**](String.md)| Tags to filter by | 
+
+### Return type
+
+[**List<Pet>**](Pet.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getPetById**
+> Pet getPetById(petId)
+
+Find pet by ID
+
+Returns a single pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to return
+
+try { 
+    var result = api_instance.getPetById(petId);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->getPetById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to return | 
+
+### Return type
+
+[**Pet**](Pet.md)
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePet**
+> updatePet(pet)
+
+Update an existing pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var pet = new Pet(); // Pet | Pet object that needs to be added to the store
+
+try { 
+    api_instance.updatePet(pet);
+} catch (e) {
+    print("Exception when calling PetApi->updatePet: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **pet** | [**Pet**](Pet.md)| Pet object that needs to be added to the store | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json, application/xml
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updatePetWithForm**
+> updatePetWithForm(petId, name, status)
+
+Updates a pet in the store with form data
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet that needs to be updated
+var name = name_example; // String | Updated name of the pet
+var status = status_example; // String | Updated status of the pet
+
+try { 
+    api_instance.updatePetWithForm(petId, name, status);
+} catch (e) {
+    print("Exception when calling PetApi->updatePetWithForm: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet that needs to be updated | 
+ **name** | **String**| Updated name of the pet | [optional] [default to null]
+ **status** | **String**| Updated status of the pet | [optional] [default to null]
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/x-www-form-urlencoded
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **uploadFile**
+> ApiResponse uploadFile(petId, additionalMetadata, file)
+
+uploads an image
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure OAuth2 access token for authorization: petstore_auth
+//openapi.api.Configuration.accessToken = 'YOUR_ACCESS_TOKEN';
+
+var api_instance = new PetApi();
+var petId = 789; // int | ID of pet to update
+var additionalMetadata = additionalMetadata_example; // String | Additional data to pass to server
+var file = BINARY_DATA_HERE; // MultipartFile | file to upload
+
+try { 
+    var result = api_instance.uploadFile(petId, additionalMetadata, file);
+    print(result);
+} catch (e) {
+    print("Exception when calling PetApi->uploadFile: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **petId** | **int**| ID of pet to update | 
+ **additionalMetadata** | **String**| Additional data to pass to server | [optional] [default to null]
+ **file** | **MultipartFile**| file to upload | [optional] [default to null]
+
+### Return type
+
+[**ApiResponse**](ApiResponse.md)
+
+### Authorization
+
+[petstore_auth](../README.md#petstore_auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi/docs/StoreApi.md b/samples/client/petstore/dart2/openapi/docs/StoreApi.md
new file mode 100644
index 00000000000..cc0c2ac2d35
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/StoreApi.md
@@ -0,0 +1,186 @@
+# openapi.api.StoreApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**deleteOrder**](StoreApi.md#deleteOrder) | **DELETE** /store/order/{orderId} | Delete purchase order by ID
+[**getInventory**](StoreApi.md#getInventory) | **GET** /store/inventory | Returns pet inventories by status
+[**getOrderById**](StoreApi.md#getOrderById) | **GET** /store/order/{orderId} | Find purchase order by ID
+[**placeOrder**](StoreApi.md#placeOrder) | **POST** /store/order | Place an order for a pet
+
+
+# **deleteOrder**
+> deleteOrder(orderId)
+
+Delete purchase order by ID
+
+For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = orderId_example; // String | ID of the order that needs to be deleted
+
+try { 
+    api_instance.deleteOrder(orderId);
+} catch (e) {
+    print("Exception when calling StoreApi->deleteOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **String**| ID of the order that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getInventory**
+> Map<String, int> getInventory()
+
+Returns pet inventories by status
+
+Returns a map of status codes to quantities
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+// TODO Configure API key authorization: api_key
+//openapi.api.Configuration.apiKey{'api_key'} = 'YOUR_API_KEY';
+// uncomment below to setup prefix (e.g. Bearer) for API key, if needed
+//openapi.api.Configuration.apiKeyPrefix{'api_key'} = "Bearer";
+
+var api_instance = new StoreApi();
+
+try { 
+    var result = api_instance.getInventory();
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getInventory: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+**Map<String, int>**
+
+### Authorization
+
+[api_key](../README.md#api_key)
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getOrderById**
+> Order getOrderById(orderId)
+
+Find purchase order by ID
+
+For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var orderId = 789; // int | ID of pet that needs to be fetched
+
+try { 
+    var result = api_instance.getOrderById(orderId);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->getOrderById: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **orderId** | **int**| ID of pet that needs to be fetched | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **placeOrder**
+> Order placeOrder(order)
+
+Place an order for a pet
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new StoreApi();
+var order = new Order(); // Order | order placed for purchasing the pet
+
+try { 
+    var result = api_instance.placeOrder(order);
+    print(result);
+} catch (e) {
+    print("Exception when calling StoreApi->placeOrder: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **order** | [**Order**](Order.md)| order placed for purchasing the pet | 
+
+### Return type
+
+[**Order**](Order.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi/docs/Tag.md b/samples/client/petstore/dart2/openapi/docs/Tag.md
new file mode 100644
index 00000000000..ded7b32ac3d
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/Tag.md
@@ -0,0 +1,16 @@
+# openapi.model.Tag
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**name** | **String** |  | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/User.md b/samples/client/petstore/dart2/openapi/docs/User.md
new file mode 100644
index 00000000000..3761b70cf0b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/User.md
@@ -0,0 +1,22 @@
+# openapi.model.User
+
+## Load the model package
+```dart
+import 'package:openapi/api.dart';
+```
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **int** |  | [optional] [default to null]
+**username** | **String** |  | [optional] [default to null]
+**firstName** | **String** |  | [optional] [default to null]
+**lastName** | **String** |  | [optional] [default to null]
+**email** | **String** |  | [optional] [default to null]
+**password** | **String** |  | [optional] [default to null]
+**phone** | **String** |  | [optional] [default to null]
+**userStatus** | **int** | User Status | [optional] [default to null]
+
+[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
+
+
diff --git a/samples/client/petstore/dart2/openapi/docs/UserApi.md b/samples/client/petstore/dart2/openapi/docs/UserApi.md
new file mode 100644
index 00000000000..0dec271be5c
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/docs/UserApi.md
@@ -0,0 +1,349 @@
+# openapi.api.UserApi
+
+## Load the API package
+```dart
+import 'package:openapi/api.dart';
+```
+
+All URIs are relative to *http://petstore.swagger.io/v2*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**createUser**](UserApi.md#createUser) | **POST** /user | Create user
+[**createUsersWithArrayInput**](UserApi.md#createUsersWithArrayInput) | **POST** /user/createWithArray | Creates list of users with given input array
+[**createUsersWithListInput**](UserApi.md#createUsersWithListInput) | **POST** /user/createWithList | Creates list of users with given input array
+[**deleteUser**](UserApi.md#deleteUser) | **DELETE** /user/{username} | Delete user
+[**getUserByName**](UserApi.md#getUserByName) | **GET** /user/{username} | Get user by user name
+[**loginUser**](UserApi.md#loginUser) | **GET** /user/login | Logs user into the system
+[**logoutUser**](UserApi.md#logoutUser) | **GET** /user/logout | Logs out current logged in user session
+[**updateUser**](UserApi.md#updateUser) | **PUT** /user/{username} | Updated user
+
+
+# **createUser**
+> createUser(user)
+
+Create user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = new User(); // User | Created user object
+
+try { 
+    api_instance.createUser(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**User**](User.md)| Created user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithArrayInput**
+> createUsersWithArrayInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithArrayInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithArrayInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **createUsersWithListInput**
+> createUsersWithListInput(user)
+
+Creates list of users with given input array
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var user = [new List&lt;User&gt;()]; // List<User> | List of user object
+
+try { 
+    api_instance.createUsersWithListInput(user);
+} catch (e) {
+    print("Exception when calling UserApi->createUsersWithListInput: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **user** | [**List&lt;User&gt;**](List.md)| List of user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **deleteUser**
+> deleteUser(username)
+
+Delete user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be deleted
+
+try { 
+    api_instance.deleteUser(username);
+} catch (e) {
+    print("Exception when calling UserApi->deleteUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be deleted | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **getUserByName**
+> User getUserByName(username)
+
+Get user by user name
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The name that needs to be fetched. Use user1 for testing.
+
+try { 
+    var result = api_instance.getUserByName(username);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->getUserByName: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The name that needs to be fetched. Use user1 for testing. | 
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **loginUser**
+> String loginUser(username, password)
+
+Logs user into the system
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | The user name for login
+var password = password_example; // String | The password for login in clear text
+
+try { 
+    var result = api_instance.loginUser(username, password);
+    print(result);
+} catch (e) {
+    print("Exception when calling UserApi->loginUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| The user name for login | 
+ **password** | **String**| The password for login in clear text | 
+
+### Return type
+
+**String**
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: application/xml, application/json
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **logoutUser**
+> logoutUser()
+
+Logs out current logged in user session
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+
+try { 
+    api_instance.logoutUser();
+} catch (e) {
+    print("Exception when calling UserApi->logoutUser: $e\n");
+}
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
+# **updateUser**
+> updateUser(username, user)
+
+Updated user
+
+This can only be done by the logged in user.
+
+### Example 
+```dart
+import 'package:openapi/api.dart';
+
+var api_instance = new UserApi();
+var username = username_example; // String | name that need to be deleted
+var user = new User(); // User | Updated user object
+
+try { 
+    api_instance.updateUser(username, user);
+} catch (e) {
+    print("Exception when calling UserApi->updateUser: $e\n");
+}
+```
+
+### Parameters
+
+Name | Type | Description  | Notes
+------------- | ------------- | ------------- | -------------
+ **username** | **String**| name that need to be deleted | 
+ **user** | [**User**](User.md)| Updated user object | 
+
+### Return type
+
+void (empty response body)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: Not defined
+ - **Accept**: Not defined
+
+[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
+
diff --git a/samples/client/petstore/dart2/openapi/git_push.sh b/samples/client/petstore/dart2/openapi/git_push.sh
new file mode 100644
index 00000000000..8442b80bb44
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/git_push.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 openapi-pestore-perl "minor update"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+
+if [ "$git_user_id" = "" ]; then
+    git_user_id="GIT_USER_ID"
+    echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+    git_repo_id="GIT_REPO_ID"
+    echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+    release_note="Minor update"
+    echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository. 
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=`git remote`
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+    if [ "$GIT_TOKEN" = "" ]; then
+        echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git credential in your environment."
+        git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
+    else
+        git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
+    fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
+
diff --git a/samples/client/petstore/dart2/openapi/lib/api.dart b/samples/client/petstore/dart2/openapi/lib/api.dart
new file mode 100644
index 00000000000..9a64a5342b4
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api.dart
@@ -0,0 +1,27 @@
+library openapi.api;
+
+import 'dart:async';
+import 'dart:convert';
+import 'package:http/http.dart';
+
+part 'api_client.dart';
+part 'api_helper.dart';
+part 'api_exception.dart';
+part 'auth/authentication.dart';
+part 'auth/api_key_auth.dart';
+part 'auth/oauth.dart';
+part 'auth/http_basic_auth.dart';
+
+part 'api/pet_api.dart';
+part 'api/store_api.dart';
+part 'api/user_api.dart';
+
+part 'model/api_response.dart';
+part 'model/category.dart';
+part 'model/order.dart';
+part 'model/pet.dart';
+part 'model/tag.dart';
+part 'model/user.dart';
+
+
+ApiClient defaultApiClient = new ApiClient();
diff --git a/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart b/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
new file mode 100644
index 00000000000..4134e018386
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
@@ -0,0 +1,432 @@
+part of openapi.api;
+
+
+
+class PetApi {
+  final ApiClient apiClient;
+
+  PetApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Add a new pet to the store
+  ///
+  /// 
+  Future addPet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Deletes a pet
+  ///
+  /// 
+  Future deletePet(int petId, { String apiKey }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+    headerParams["api_key"] = apiKey;
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Finds Pets by status
+  ///
+  /// Multiple status values can be provided with comma separated strings
+  Future<List<Pet>> findPetsByStatus(List<String> status) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(status == null) {
+     throw new ApiException(400, "Missing required param: status");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByStatus".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "status", status));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Finds Pets by tags
+  ///
+  /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
+  Future<List<Pet>> findPetsByTags(List<String> tags) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(tags == null) {
+     throw new ApiException(400, "Missing required param: tags");
+    }
+
+    // create path and map variables
+    String path = "/pet/findByTags".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("csv", "tags", tags));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return (apiClient.deserialize(response.body, 'List<Pet>') as List).map((item) => item as Pet).toList();
+    } else {
+      return null;
+    }
+  }
+  /// Find pet by ID
+  ///
+  /// Returns a single pet
+  Future<Pet> getPetById(int petId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Pet') as Pet;
+    } else {
+      return null;
+    }
+  }
+  /// Update an existing pet
+  ///
+  /// 
+  Future updatePet(Pet pet) async {
+    Object postBody = pet;
+
+    // verify required params are set
+    if(pet == null) {
+     throw new ApiException(400, "Missing required param: pet");
+    }
+
+    // create path and map variables
+    String path = "/pet".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/json","application/xml"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updates a pet in the store with form data
+  ///
+  /// 
+  Future updatePetWithForm(int petId, { String name, String status }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["application/x-www-form-urlencoded"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (name != null) {
+        hasFields = true;
+        mp.fields['name'] = parameterToString(name);
+      }
+      if (status != null) {
+        hasFields = true;
+        mp.fields['status'] = parameterToString(status);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (name != null)
+        formParams['name'] = parameterToString(name);
+      if (status != null)
+        formParams['status'] = parameterToString(status);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// uploads an image
+  ///
+  /// 
+  Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(petId == null) {
+     throw new ApiException(400, "Missing required param: petId");
+    }
+
+    // create path and map variables
+    String path = "/pet/{petId}/uploadImage".replaceAll("{format}","json").replaceAll("{" + "petId" + "}", petId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = ["multipart/form-data"];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["petstore_auth"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if (additionalMetadata != null) {
+        hasFields = true;
+        mp.fields['additionalMetadata'] = parameterToString(additionalMetadata);
+      }
+      if (file != null) {
+        hasFields = true;
+        mp.fields['file'] = file.field;
+        mp.files.add(file);
+      }
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+      if (additionalMetadata != null)
+        formParams['additionalMetadata'] = parameterToString(additionalMetadata);
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'ApiResponse') as ApiResponse;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/api/store_api.dart b/samples/client/petstore/dart2/openapi/lib/api/store_api.dart
new file mode 100644
index 00000000000..f2a48f2d4da
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api/store_api.dart
@@ -0,0 +1,207 @@
+part of openapi.api;
+
+
+
+class StoreApi {
+  final ApiClient apiClient;
+
+  StoreApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Delete purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
+  Future deleteOrder(String orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Returns pet inventories by status
+  ///
+  /// Returns a map of status codes to quantities
+  Future<Map<String, int>> getInventory() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/store/inventory".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = ["api_key"];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return new Map<String, int>.from(apiClient.deserialize(response.body, 'Map<String, int>'));
+          ;
+    } else {
+      return null;
+    }
+  }
+  /// Find purchase order by ID
+  ///
+  /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
+  Future<Order> getOrderById(int orderId) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(orderId == null) {
+     throw new ApiException(400, "Missing required param: orderId");
+    }
+
+    // create path and map variables
+    String path = "/store/order/{orderId}".replaceAll("{format}","json").replaceAll("{" + "orderId" + "}", orderId.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+  /// Place an order for a pet
+  ///
+  /// 
+  Future<Order> placeOrder(Order order) async {
+    Object postBody = order;
+
+    // verify required params are set
+    if(order == null) {
+     throw new ApiException(400, "Missing required param: order");
+    }
+
+    // create path and map variables
+    String path = "/store/order".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'Order') as Order;
+    } else {
+      return null;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/api/user_api.dart b/samples/client/petstore/dart2/openapi/lib/api/user_api.dart
new file mode 100644
index 00000000000..cf8ef6bf800
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api/user_api.dart
@@ -0,0 +1,409 @@
+part of openapi.api;
+
+
+
+class UserApi {
+  final ApiClient apiClient;
+
+  UserApi([ApiClient apiClient]) : apiClient = apiClient ?? defaultApiClient;
+
+  /// Create user
+  ///
+  /// This can only be done by the logged in user.
+  Future createUser(User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithArrayInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithArray".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Creates list of users with given input array
+  ///
+  /// 
+  Future createUsersWithListInput(List<User> user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/createWithList".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'POST',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Delete user
+  ///
+  /// This can only be done by the logged in user.
+  Future deleteUser(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'DELETE',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Get user by user name
+  ///
+  /// 
+  Future<User> getUserByName(String username) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'User') as User;
+    } else {
+      return null;
+    }
+  }
+  /// Logs user into the system
+  ///
+  /// 
+  Future<String> loginUser(String username, String password) async {
+    Object postBody = null;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(password == null) {
+     throw new ApiException(400, "Missing required param: password");
+    }
+
+    // create path and map variables
+    String path = "/user/login".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+      queryParams.addAll(_convertParametersForCollectionFormat("", "username", username));
+      queryParams.addAll(_convertParametersForCollectionFormat("", "password", password));
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+      return apiClient.deserialize(response.body, 'String') as String;
+    } else {
+      return null;
+    }
+  }
+  /// Logs out current logged in user session
+  ///
+  /// 
+  Future logoutUser() async {
+    Object postBody = null;
+
+    // verify required params are set
+
+    // create path and map variables
+    String path = "/user/logout".replaceAll("{format}","json");
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'GET',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+  /// Updated user
+  ///
+  /// This can only be done by the logged in user.
+  Future updateUser(String username, User user) async {
+    Object postBody = user;
+
+    // verify required params are set
+    if(username == null) {
+     throw new ApiException(400, "Missing required param: username");
+    }
+    if(user == null) {
+     throw new ApiException(400, "Missing required param: user");
+    }
+
+    // create path and map variables
+    String path = "/user/{username}".replaceAll("{format}","json").replaceAll("{" + "username" + "}", username.toString());
+
+    // query params
+    List<QueryParam> queryParams = [];
+    Map<String, String> headerParams = {};
+    Map<String, String> formParams = {};
+
+    List<String> contentTypes = [];
+
+    String contentType = contentTypes.length > 0 ? contentTypes[0] : "application/json";
+    List<String> authNames = [];
+
+    if(contentType.startsWith("multipart/form-data")) {
+      bool hasFields = false;
+      MultipartRequest mp = new MultipartRequest(null, null);
+      if(hasFields)
+        postBody = mp;
+    }
+    else {
+    }
+
+    var response = await apiClient.invokeAPI(path,
+                                             'PUT',
+                                             queryParams,
+                                             postBody,
+                                             headerParams,
+                                             formParams,
+                                             contentType,
+                                             authNames);
+
+    if(response.statusCode >= 400) {
+      throw new ApiException(response.statusCode, response.body);
+    } else if(response.body != null) {
+    } else {
+      return;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/api_client.dart b/samples/client/petstore/dart2/openapi/lib/api_client.dart
new file mode 100644
index 00000000000..db4116dd96d
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api_client.dart
@@ -0,0 +1,160 @@
+part of openapi.api;
+
+class QueryParam {
+  String name;
+  String value;
+
+  QueryParam(this.name, this.value);
+}
+
+class ApiClient {
+
+  String basePath;
+  var client = new Client();
+
+  Map<String, String> _defaultHeaderMap = {};
+  Map<String, Authentication> _authentications = {};
+
+  final _RegList = new RegExp(r'^List<(.*)>$');
+  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+
+  ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
+    // Setup authentications (key: authentication name, value: authentication).
+    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = new OAuth();
+  }
+
+  void addDefaultHeader(String key, String value) {
+     _defaultHeaderMap[key] = value;
+  }
+
+  dynamic _deserialize(dynamic value, String targetType) {
+    try {
+      switch (targetType) {
+        case 'String':
+          return '$value';
+        case 'int':
+          return value is int ? value : int.parse('$value');
+        case 'bool':
+          return value is bool ? value : '$value'.toLowerCase() == 'true';
+        case 'double':
+          return value is double ? value : double.parse('$value');
+        case 'ApiResponse':
+          return new ApiResponse.fromJson(value);
+        case 'Category':
+          return new Category.fromJson(value);
+        case 'Order':
+          return new Order.fromJson(value);
+        case 'Pet':
+          return new Pet.fromJson(value);
+        case 'Tag':
+          return new Tag.fromJson(value);
+        case 'User':
+          return new User.fromJson(value);
+        default:
+          {
+            Match match;
+            if (value is List &&
+                (match = _RegList.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return value.map((v) => _deserialize(v, newTargetType)).toList();
+            } else if (value is Map &&
+                (match = _RegMap.firstMatch(targetType)) != null) {
+              var newTargetType = match[1];
+              return new Map.fromIterables(value.keys,
+                  value.values.map((v) => _deserialize(v, newTargetType)));
+            }
+          }
+      }
+    } catch (e, stack) {
+      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+    }
+    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+  }
+
+  dynamic deserialize(String json, String targetType) {
+    // Remove all spaces.  Necessary for reg expressions as well.
+    targetType = targetType.replaceAll(' ', '');
+
+    if (targetType == 'String') return json;
+
+    var decodedJson = JSON.decode(json);
+    return _deserialize(decodedJson, targetType);
+  }
+
+  String serialize(Object obj) {
+    String serialized = '';
+    if (obj == null) {
+      serialized = '';
+    } else {
+      serialized = JSON.encode(obj);
+    }
+    return serialized;
+  }
+
+  // We don't use a Map<String, String> for queryParams.
+  // If collectionFormat is 'multi' a key might appear multiple times.
+  Future<Response> invokeAPI(String path,
+                             String method,
+                             Iterable<QueryParam> queryParams,
+                             Object body,
+                             Map<String, String> headerParams,
+                             Map<String, String> formParams,
+                             String contentType,
+                             List<String> authNames) async {
+
+    _updateParamsForAuth(authNames, queryParams, headerParams);
+
+    var ps = queryParams.where((p) => p.value != null).map((p) => '${p.name}=${p.value}');
+    String queryString = ps.isNotEmpty ?
+                         '?' + ps.join('&') :
+                         '';
+
+    String url = basePath + path + queryString;
+
+    headerParams.addAll(_defaultHeaderMap);
+    headerParams['Content-Type'] = contentType;
+
+    if(body is MultipartRequest) {
+      var request = new MultipartRequest(method, Uri.parse(url));
+      request.fields.addAll(body.fields);
+      request.files.addAll(body.files);
+      request.headers.addAll(body.headers);
+      request.headers.addAll(headerParams);
+      var response = await client.send(request);
+      return Response.fromStream(response);
+    } else {
+      var msgBody = contentType == "application/x-www-form-urlencoded" ? formParams : serialize(body);
+      switch(method) {
+        case "POST":
+          return client.post(url, headers: headerParams, body: msgBody);
+        case "PUT":
+          return client.put(url, headers: headerParams, body: msgBody);
+        case "DELETE":
+          return client.delete(url, headers: headerParams);
+        case "PATCH":
+          return client.patch(url, headers: headerParams, body: msgBody);
+        default:
+          return client.get(url, headers: headerParams);
+      }
+    }
+  }
+
+  /// Update query and header parameters based on authentication settings.
+  /// @param authNames The authentications to apply
+  void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
+    authNames.forEach((authName) {
+      Authentication auth = _authentications[authName];
+      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      auth.applyToParams(queryParams, headerParams);
+    });
+  }
+
+  void setAccessToken(String accessToken) {
+    _authentications.forEach((key, auth) {
+      if (auth is OAuth) {
+        auth.setAccessToken(accessToken);
+      }
+    });
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/api_exception.dart b/samples/client/petstore/dart2/openapi/lib/api_exception.dart
new file mode 100644
index 00000000000..f188fd125a4
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api_exception.dart
@@ -0,0 +1,23 @@
+part of openapi.api;
+
+class ApiException implements Exception {
+  int code = 0;
+  String message = null;
+  Exception innerException = null;
+  StackTrace stackTrace = null;
+
+  ApiException(this.code, this.message);
+
+  ApiException.withInner(this.code, this.message, this.innerException, this.stackTrace);
+
+  String toString() {
+    if (message == null) return "ApiException";
+
+    if (innerException == null) {
+      return "ApiException $code: $message";
+    }
+
+    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+        stackTrace.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/api_helper.dart b/samples/client/petstore/dart2/openapi/lib/api_helper.dart
new file mode 100644
index 00000000000..79af4521d5b
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/api_helper.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+const _delimiters = const {'csv': ',', 'ssv': ' ', 'tsv': '\t', 'pipes': '|'};
+
+// port from Java version
+Iterable<QueryParam> _convertParametersForCollectionFormat(
+  String collectionFormat, String name, dynamic value) {
+  var params = <QueryParam>[];
+
+  // preconditions
+  if (name == null || name.isEmpty || value == null) return params;
+
+  if (value is! List) {
+    params.add(new QueryParam(name, parameterToString(value)));
+    return params;
+  }
+
+  List values = value as List;
+
+  // get the collection format
+  collectionFormat = (collectionFormat == null || collectionFormat.isEmpty)
+                     ? "csv"
+                     : collectionFormat; // default: csv
+
+  if (collectionFormat == "multi") {
+    return values.map((v) => new QueryParam(name, parameterToString(v)));
+  }
+
+  String delimiter = _delimiters[collectionFormat] ?? ",";
+
+  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  return params;
+}
+
+/// Format the given parameter object into string.
+String parameterToString(dynamic value) {
+  if (value == null) {
+    return '';
+  } else if (value is DateTime) {
+    return value.toUtc().toIso8601String();
+  } else {
+    return value.toString();
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
new file mode 100644
index 00000000000..f9617f7ae4d
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
@@ -0,0 +1,27 @@
+part of openapi.api;
+
+class ApiKeyAuth implements Authentication {
+
+  final String location;
+  final String paramName;
+  String apiKey;
+  String apiKeyPrefix;
+
+  ApiKeyAuth(this.location, this.paramName);
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String value;
+    if (apiKeyPrefix != null) {
+      value = '$apiKeyPrefix $apiKey';
+    } else {
+      value = apiKey;
+    }
+
+    if (location == 'query' && value != null) {
+      queryParams.add(new QueryParam(paramName, value));
+    } else if (location == 'header' && value != null) {
+      headerParams[paramName] = value;
+    }
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/authentication.dart b/samples/client/petstore/dart2/openapi/lib/auth/authentication.dart
new file mode 100644
index 00000000000..abd5e2fe68a
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/auth/authentication.dart
@@ -0,0 +1,7 @@
+part of openapi.api;
+
+abstract class Authentication {
+
+	/// Apply authentication settings to header and query params.
+	void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams);
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
new file mode 100644
index 00000000000..4e77ddcf6e6
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
@@ -0,0 +1,14 @@
+part of openapi.api;
+
+class HttpBasicAuth implements Authentication {
+
+  String username;
+  String password;
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
+    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+  }
+
+}
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart b/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
new file mode 100644
index 00000000000..13bfd799743
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
@@ -0,0 +1,19 @@
+part of openapi.api;
+
+class OAuth implements Authentication {
+  String accessToken;
+
+  OAuth({this.accessToken}) {
+  }
+
+  @override
+  void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
+    if (accessToken != null) {
+      headerParams["Authorization"] = "Bearer " + accessToken;
+    }
+  }
+
+  void setAccessToken(String accessToken) {
+    this.accessToken = accessToken;
+  }
+}
diff --git a/samples/client/petstore/dart2/openapi/lib/model/api_response.dart b/samples/client/petstore/dart2/openapi/lib/model/api_response.dart
new file mode 100644
index 00000000000..a39d9500b29
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/api_response.dart
@@ -0,0 +1,44 @@
+part of openapi.api;
+
+class ApiResponse {
+  
+  int code = null;
+  
+  String type = null;
+  
+  String message = null;
+  ApiResponse();
+
+  @override
+  String toString() {
+    return 'ApiResponse[code=$code, type=$type, message=$message, ]';
+  }
+
+  ApiResponse.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    code = json['code'];
+    type = json['type'];
+    message = json['message'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'code': code,
+      'type': type,
+      'message': message
+    };
+  }
+
+  static List<ApiResponse> listFromJson(List<dynamic> json) {
+    return json == null ? new List<ApiResponse>() : json.map((value) => new ApiResponse.fromJson(value)).toList();
+  }
+
+  static Map<String, ApiResponse> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, ApiResponse>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new ApiResponse.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/lib/model/category.dart b/samples/client/petstore/dart2/openapi/lib/model/category.dart
new file mode 100644
index 00000000000..b9b2481dd29
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/category.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Category {
+  
+  int id = null;
+  
+  String name = null;
+  Category();
+
+  @override
+  String toString() {
+    return 'Category[id=$id, name=$name, ]';
+  }
+
+  Category.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Category> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Category>() : json.map((value) => new Category.fromJson(value)).toList();
+  }
+
+  static Map<String, Category> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Category>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Category.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/lib/model/order.dart b/samples/client/petstore/dart2/openapi/lib/model/order.dart
new file mode 100644
index 00000000000..4e264a183ef
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/order.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Order {
+  
+  int id = null;
+  
+  int petId = null;
+  
+  int quantity = null;
+  
+  DateTime shipDate = null;
+  /* Order Status */
+  String status = null;
+  //enum statusEnum {  placed,  approved,  delivered,  };{
+  
+  bool complete = false;
+  Order();
+
+  @override
+  String toString() {
+    return 'Order[id=$id, petId=$petId, quantity=$quantity, shipDate=$shipDate, status=$status, complete=$complete, ]';
+  }
+
+  Order.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    petId = json['petId'];
+    quantity = json['quantity'];
+    shipDate = json['shipDate'] == null ? null : DateTime.parse(json['shipDate']);
+    status = json['status'];
+    complete = json['complete'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'petId': petId,
+      'quantity': quantity,
+      'shipDate': shipDate == null ? '' : shipDate.toUtc().toIso8601String(),
+      'status': status,
+      'complete': complete
+    };
+  }
+
+  static List<Order> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Order>() : json.map((value) => new Order.fromJson(value)).toList();
+  }
+
+  static Map<String, Order> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Order>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Order.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/lib/model/pet.dart b/samples/client/petstore/dart2/openapi/lib/model/pet.dart
new file mode 100644
index 00000000000..4d2f77a1a5a
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/pet.dart
@@ -0,0 +1,57 @@
+part of openapi.api;
+
+class Pet {
+  
+  int id = null;
+  
+  Category category = null;
+  
+  String name = null;
+  
+  List<String> photoUrls = [];
+  
+  List<Tag> tags = [];
+  /* pet status in the store */
+  String status = null;
+  //enum statusEnum {  available,  pending,  sold,  };{
+  Pet();
+
+  @override
+  String toString() {
+    return 'Pet[id=$id, category=$category, name=$name, photoUrls=$photoUrls, tags=$tags, status=$status, ]';
+  }
+
+  Pet.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    category = new Category.fromJson(json['category']);
+    name = json['name'];
+    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    tags = Tag.listFromJson(json['tags']);
+    status = json['status'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'category': category,
+      'name': name,
+      'photoUrls': photoUrls,
+      'tags': tags,
+      'status': status
+    };
+  }
+
+  static List<Pet> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Pet>() : json.map((value) => new Pet.fromJson(value)).toList();
+  }
+
+  static Map<String, Pet> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Pet>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Pet.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/lib/model/tag.dart b/samples/client/petstore/dart2/openapi/lib/model/tag.dart
new file mode 100644
index 00000000000..315a326adb7
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/tag.dart
@@ -0,0 +1,40 @@
+part of openapi.api;
+
+class Tag {
+  
+  int id = null;
+  
+  String name = null;
+  Tag();
+
+  @override
+  String toString() {
+    return 'Tag[id=$id, name=$name, ]';
+  }
+
+  Tag.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    name = json['name'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'name': name
+    };
+  }
+
+  static List<Tag> listFromJson(List<dynamic> json) {
+    return json == null ? new List<Tag>() : json.map((value) => new Tag.fromJson(value)).toList();
+  }
+
+  static Map<String, Tag> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, Tag>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new Tag.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/lib/model/user.dart b/samples/client/petstore/dart2/openapi/lib/model/user.dart
new file mode 100644
index 00000000000..0e4cc2104c7
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/lib/model/user.dart
@@ -0,0 +1,64 @@
+part of openapi.api;
+
+class User {
+  
+  int id = null;
+  
+  String username = null;
+  
+  String firstName = null;
+  
+  String lastName = null;
+  
+  String email = null;
+  
+  String password = null;
+  
+  String phone = null;
+  /* User Status */
+  int userStatus = null;
+  User();
+
+  @override
+  String toString() {
+    return 'User[id=$id, username=$username, firstName=$firstName, lastName=$lastName, email=$email, password=$password, phone=$phone, userStatus=$userStatus, ]';
+  }
+
+  User.fromJson(Map<String, dynamic> json) {
+    if (json == null) return;
+    id = json['id'];
+    username = json['username'];
+    firstName = json['firstName'];
+    lastName = json['lastName'];
+    email = json['email'];
+    password = json['password'];
+    phone = json['phone'];
+    userStatus = json['userStatus'];
+  }
+
+  Map<String, dynamic> toJson() {
+    return {
+      'id': id,
+      'username': username,
+      'firstName': firstName,
+      'lastName': lastName,
+      'email': email,
+      'password': password,
+      'phone': phone,
+      'userStatus': userStatus
+    };
+  }
+
+  static List<User> listFromJson(List<dynamic> json) {
+    return json == null ? new List<User>() : json.map((value) => new User.fromJson(value)).toList();
+  }
+
+  static Map<String, User> mapFromJson(Map<String, Map<String, dynamic>> json) {
+    var map = new Map<String, User>();
+    if (json != null && json.length > 0) {
+      json.forEach((String key, Map<String, dynamic> value) => map[key] = new User.fromJson(value));
+    }
+    return map;
+  }
+}
+
diff --git a/samples/client/petstore/dart2/openapi/pubspec.yaml b/samples/client/petstore/dart2/openapi/pubspec.yaml
new file mode 100644
index 00000000000..d54efb46a2e
--- /dev/null
+++ b/samples/client/petstore/dart2/openapi/pubspec.yaml
@@ -0,0 +1,5 @@
+name: openapi
+version: 1.0.0
+description: OpenAPI API client
+dependencies:
+  http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/petstore/.analysis_options b/samples/client/petstore/dart2/petstore/.analysis_options
new file mode 100644
index 00000000000..a10d4c5a05c
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
diff --git a/samples/client/petstore/dart2/petstore/README.md b/samples/client/petstore/dart2/petstore/README.md
new file mode 100644
index 00000000000..17343a5c026
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/README.md
@@ -0,0 +1,58 @@
+# To run these tests:
+
+Simply start the dart server: `pub serve`
+
+then open http://127.0.0.1:8080/tests.html
+
+
+This already starts the tests.  There is _NO_ feedback!
+
+Open the javascript / dart console of your browser to verify all tests 
+passed successfully.
+
+You should have the following output:
+```
+Observatory listening at http://127.0.0.1:39067/
+unittest-suite-wait-for-done
+GET http://petstore.swagger.io/v2/pet/957639 404 (Not Found)
+GET http://petstore.swagger.io/v2/pet/525946 404 (Not Found)
+GET http://petstore.swagger.io/v2/store/order/29756 404 (Not Found)
+GET http://petstore.swagger.io/v2/user/Riddlem325 404 (Not Found)
+PASS: Pet API  adds a new pet and gets it by id
+PASS: Pet API  doesn't get non-existing pet by id
+PASS: Pet API  deletes existing pet by id
+PASS: Pet API  updates pet with form
+PASS: Pet API  updates existing pet
+PASS: Pet API  finds pets by status
+PASS: Pet API  finds pets by tag
+PASS: Pet API  uploads a pet image
+PASS: Store API  places an order and gets it by id
+PASS: Store API  deletes an order
+PASS: Store API  gets the store inventory
+PASS: User API  creates a user
+PASS: User API  creates users with list input
+PASS: User API  updates a user
+PASS: User API  deletes a user
+PASS: User API  logs a user in
+
+All 16 tests passed.
+unittest-suite-success
+```
+
+
+You may also run the tests in the dart vm.
+
+Either generate the test-package for a vm:
+- change bin/dart-petstore.sh and uncomment the vm options line
+- run bin/dart-petstore.sh
+
+or
+
+- in `lib/api_client.dart` change `new BrowserClient()` to `new Client()`
+- in `lib/api.dart` remove the line `import 'package:http/browser_client.dart';`
+
+
+
+Then run `test/tests.dart`.
+
+Have fun.
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/petstore/pom.xml b/samples/client/petstore/dart2/petstore/pom.xml
new file mode 100644
index 00000000000..787349feb66
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/pom.xml
@@ -0,0 +1,60 @@
+<project>
+    <modelVersion>4.0.0</modelVersion>
+    <groupId>org.openapitools</groupId>
+    <artifactId>Dart2PetstoreClientTests</artifactId>
+    <packaging>pom</packaging>
+    <version>1.0.0-SNAPSHOT</version>
+    <name>Dart2 Petstore Client</name>
+    <build>
+        <plugins>
+            <plugin>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}</outputDirectory>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <version>1.2.1</version>
+                <executions>
+                    <execution>
+                        <id>pub-get</id>
+                        <phase>pre-integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <executable>pub</executable>
+                            <arguments>
+                                <argument>get</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                    <execution>
+                        <id>pub-test</id>
+                        <phase>integration-test</phase>
+                        <goals>
+                            <goal>exec</goal>
+                        </goals>
+                        <configuration>
+                            <executable>pub</executable>
+                            <arguments>
+                                <argument>build</argument>
+                                <argument>test</argument>
+                            </arguments>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/samples/client/petstore/dart2/petstore/pubspec.yaml b/samples/client/petstore/dart2/petstore/pubspec.yaml
new file mode 100644
index 00000000000..373c848db59
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/pubspec.yaml
@@ -0,0 +1,9 @@
+name: petstore_client
+version: 1.0.0
+description: Petstore client using OpenAPI library
+dependencies:
+  openapi:
+    path: ../openapi-browser-client
+  browser: any
+dev_dependencies:
+  guinness: '^0.1.17'
diff --git a/samples/client/petstore/dart2/petstore/test/pet_test.dart b/samples/client/petstore/dart2/petstore/test/pet_test.dart
new file mode 100644
index 00000000000..213396f29cb
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/pet_test.dart
@@ -0,0 +1,81 @@
+part of tests;
+
+testPetApi() {
+  var petApi = new PetApi();
+
+  describe('Pet API ', () {
+    it('adds a new pet and gets it by id', () async {
+      var id = newId();
+
+      await petApi.addPet(new Pet()..id = id);
+      var pet = await petApi.getPetById(id);
+      expect(pet.id).toEqual(id);
+    });
+
+    it('doesn\'t get non-existing pet by id', () {
+      expect(petApi.getPetById(newId()))
+          .toThrowWith(anInstanceOf: ApiException);
+    });
+
+    it('deletes existing pet by id', () async {
+      var id = newId();
+      await petApi.addPet(new Pet()..id = id);
+      await petApi.deletePet(id, apiKey: 'special-key');
+      expect(petApi.getPetById(id)).toThrowWith(anInstanceOf: ApiException);
+    });
+
+    it('updates pet with form', () async {
+      var id = newId();
+      await petApi.addPet(new Pet()
+        ..id = id
+        ..name = 'Snowy');
+      await petApi.updatePetWithForm(id, name: 'Doge', status: '');
+      var pet = await petApi.getPetById(id);
+      expect(pet.name).toEqual('Doge');
+    });
+
+    it('updates existing pet', () async {
+      var id = newId();
+      var name = 'Snowy';
+
+      await petApi.addPet(new Pet()..id = id);
+      await petApi.updatePet(new Pet()
+        ..id = id
+        ..name = name);
+      var pet = await petApi.getPetById(id);
+      expect(pet.name).toEqual(name);
+    });
+
+    it('finds pets by status', () async {
+      var id1 = newId();
+      var id2 = newId();
+      var id3 = newId();
+      var status = 'available';
+
+      return Future.wait([
+        petApi.addPet(new Pet()
+          ..id = id1
+          ..status = status),
+        petApi.addPet(new Pet()
+          ..id = id2
+          ..status = status),
+        petApi.addPet(new Pet()
+          ..id = id3
+          ..status = 'sold')
+      ]).then((_) async {
+        var pets = await petApi.findPetsByStatus([status]);
+        var petIds = pets.map((pet) => pet.id).toList();
+        expect(petIds).toContain(id1);
+        expect(petIds).toContain(id2);
+        expect(petIds).not.toContain(id3);
+      });
+    });
+
+    it('uploads a pet image', () async {
+      var id = newId();
+      await petApi.addPet(new Pet()..id = id);
+      var file = new MultipartFile.fromBytes('file', [104, 101, 108, 108, 111]);
+      await petApi.uploadFile(id, additionalMetadata: '', file: file);
+    });
+  });
+}
diff --git a/samples/client/petstore/dart2/petstore/test/store_test.dart b/samples/client/petstore/dart2/petstore/test/store_test.dart
new file mode 100644
index 00000000000..39d9cecfac7
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/store_test.dart
@@ -0,0 +1,28 @@
+part of tests;
+
+testStoreApi() {
+  var storeApi = new StoreApi();
+
+  describe('Store API ', () {
+    it('places an order and gets it by id', () async {
+      var id = newId();
+
+      await storeApi.placeOrder(new Order()..id = id);
+      var order = await storeApi.getOrderById(id);
+      expect(order.id).toEqual(id);
+    });
+
+    it('deletes an order', () async {
+      var id = newId();
+
+      await storeApi.placeOrder(new Order()..id = id);
+      await storeApi.deleteOrder(id.toString());
+      expect(storeApi.getOrderById(id)).toThrowWith(anInstanceOf: ApiException);
+    });
+
+    it('gets the store inventory', () async {
+      Map<String, int> inventory = await storeApi.getInventory();
+      expect(inventory.length).not.toBe(0);
+    });
+  });
+}
diff --git a/samples/client/petstore/dart2/petstore/test/tests.dart b/samples/client/petstore/dart2/petstore/test/tests.dart
new file mode 100644
index 00000000000..cea11e15a9c
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/tests.dart
@@ -0,0 +1,23 @@
+library tests;
+
+import 'dart:async';
+import 'dart:math';
+import 'package:http/http.dart';
+import 'package:guinness/guinness.dart';
+import 'package:openapi/api.dart';
+
+part 'pet_test.dart';
+part 'store_test.dart';
+part 'user_test.dart';
+
+final random = new Random();
+
+int newId() {
+  return random.nextInt(999999);
+}
+
+main() {
+  testPetApi();
+  testStoreApi();
+  testUserApi();
+}
diff --git a/samples/client/petstore/dart2/petstore/test/tests.html b/samples/client/petstore/dart2/petstore/test/tests.html
new file mode 100644
index 00000000000..e3796c5fcfe
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/tests.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Unit Test Results</title>
+</head>
+
+<body>
+<script type="application/dart" src="tests.dart"></script>
+<script src="packages/browser/dart.js"></script>
+</body>
+</html>
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/petstore/test/user_test.dart b/samples/client/petstore/dart2/petstore/test/user_test.dart
new file mode 100644
index 00000000000..7188a1d25ea
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/user_test.dart
@@ -0,0 +1,77 @@
+part of tests;
+
+testUserApi() {
+  var userApi = new UserApi();
+
+  describe('User API ', () {
+    it('creates a user', () async {
+      var id = newId();
+      var username = 'Mally45';
+      await userApi.createUser(new User()
+        ..id = id
+        ..username = username);
+      var user = await userApi.getUserByName(username);
+      expect(user.id).toEqual(id);
+    });
+
+    it('creates users with list input', () async {
+      var firstId = newId();
+      var joe = 'Joe';
+
+      var sally = 'Sally';
+      var secondId = newId();
+
+      var users = [
+        new User()
+          ..id = firstId
+          ..username = joe,
+        new User()
+          ..id = secondId
+          ..username = sally
+      ];
+
+      await userApi.createUsersWithListInput(users);
+      var firstUser = await userApi.getUserByName(joe);
+      var secondUser = await userApi.getUserByName(sally);
+      expect(firstUser.id).toEqual(firstId);
+      expect(secondUser.id).toEqual(secondId);
+    });
+
+    it('updates a user', () async {
+      var username = 'Arkjam89';
+      var email = 'test@example.com';
+      var user = new User()
+        ..id = newId()
+        ..username = username;
+
+      await userApi.createUser(user);
+      user.email = email;
+      await userApi.updateUser(username, user);
+      var foundUser = await userApi.getUserByName(username);
+      expect(foundUser.email).toEqual(email);
+    });
+
+    it('deletes a user', () async {
+      var username = 'Riddlem325';
+      await userApi.createUser(new User()
+        ..id = newId()
+        ..username = username);
+      await userApi.deleteUser(username);
+      expect(userApi.getUserByName(username))
+          .toThrowWith(anInstanceOf: ApiException);
+    });
+
+    it('logs a user in', () async {
+      var username = 'sgarad625';
+      var password = 'lokimoki1';
+      var user = new User()
+        ..id = newId()
+        ..username = username
+        ..password = password;
+
+      await userApi.createUser(user);
+      var result = await userApi.loginUser(username, password);
+      expect(result).toContain('logged in user session:');
+    });
+  });
+}
-- 
GitLab


From 00c5f890f2458dc406ee3d49a0b843b1181ceb32 Mon Sep 17 00:00:00 2001
From: William Cheng <wing328hk@gmail.com>
Date: Fri, 24 Aug 2018 13:05:29 +0800
Subject: [PATCH 03/16] fix dart installation

---
 .travis.yml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/.travis.yml b/.travis.yml
index fa01bd2528a..e7ba951274f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -72,6 +72,11 @@ before_install:
   - sudo apt-get install -qq bats
   - sudo apt-get install -qq curl
   # install dart
+  #- sudo apt-get update
+  - sudo apt-get install apt-transport-https
+  - sudo sh -c 'curl https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -'
+  - sudo sh -c 'curl https://storage.googleapis.com/download.dartlang.org/linux/debian/dart_stable.list > /etc/apt/sources.list.d/dart_stable.list'
+  - sudo apt-get update
   - sudo apt-get install dart
   # install perl module
   #- cpanm --local-lib=~/perl5 local::lib && eval $(perl -I ~/perl5/lib/perl5/ -Mlocal::lib)
-- 
GitLab


From 73c57e8955075b544eec135c4094a46bcd76d8db Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 11:02:05 +0800
Subject: [PATCH 04/16] Upper constraints on the SDK version

---
 .../client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml | 2 ++
 .../client/petstore/dart2/openapi-browser-client/pubspec.yaml   | 2 ++
 samples/client/petstore/dart2/openapi/pubspec.yaml              | 2 ++
 samples/client/petstore/dart2/petstore/pubspec.yaml             | 2 ++
 4 files changed, 8 insertions(+)

diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi/pubspec.yaml b/samples/client/petstore/dart2/openapi/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/petstore/pubspec.yaml b/samples/client/petstore/dart2/petstore/pubspec.yaml
index 373c848db59..cd9abef5a9f 100644
--- a/samples/client/petstore/dart2/petstore/pubspec.yaml
+++ b/samples/client/petstore/dart2/petstore/pubspec.yaml
@@ -1,6 +1,8 @@
 name: petstore_client
 version: 1.0.0
 description: Petstore client using OpenAPI library
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   openapi:
     path: ../openapi-browser-client
-- 
GitLab


From 0a9c838711f1cd0ab554491d9c0734db0869de38 Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 11:19:40 +0800
Subject: [PATCH 05/16] Update dependencies

---
 .../petstore/dart2/petstore/pubspec.lock      | 516 ++++++++++++++++++
 .../petstore/dart2/petstore/pubspec.yaml      |   6 +-
 2 files changed, 520 insertions(+), 2 deletions(-)
 create mode 100644 samples/client/petstore/dart2/petstore/pubspec.lock

diff --git a/samples/client/petstore/dart2/petstore/pubspec.lock b/samples/client/petstore/dart2/petstore/pubspec.lock
new file mode 100644
index 00000000000..ef8517fab6a
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/pubspec.lock
@@ -0,0 +1,516 @@
+# Generated by pub
+# See https://www.dartlang.org/tools/pub/glossary#lockfile
+packages:
+  analyzer:
+    dependency: transitive
+    description:
+      name: analyzer
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.32.4"
+  archive:
+    dependency: transitive
+    description:
+      name: archive
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.4"
+  args:
+    dependency: transitive
+    description:
+      name: args
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.5.0"
+  async:
+    dependency: transitive
+    description:
+      name: async
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.8"
+  bazel_worker:
+    dependency: transitive
+    description:
+      name: bazel_worker
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.12"
+  boolean_selector:
+    dependency: transitive
+    description:
+      name: boolean_selector
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.4"
+  build:
+    dependency: transitive
+    description:
+      name: build
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.12.7+3"
+  build_config:
+    dependency: transitive
+    description:
+      name: build_config
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.1+2"
+  build_modules:
+    dependency: transitive
+    description:
+      name: build_modules
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.2"
+  build_resolvers:
+    dependency: transitive
+    description:
+      name: build_resolvers
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.2+3"
+  build_runner:
+    dependency: "direct dev"
+    description:
+      name: build_runner
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.10.1+1"
+  build_runner_core:
+    dependency: transitive
+    description:
+      name: build_runner_core
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.1+4"
+  build_test:
+    dependency: "direct dev"
+    description:
+      name: build_test
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.10.3+1"
+  build_web_compilers:
+    dependency: "direct dev"
+    description:
+      name: build_web_compilers
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.4.2+2"
+  built_collection:
+    dependency: transitive
+    description:
+      name: built_collection
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.3"
+  built_value:
+    dependency: transitive
+    description:
+      name: built_value
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "5.5.5"
+  charcode:
+    dependency: transitive
+    description:
+      name: charcode
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.2"
+  cli_util:
+    dependency: transitive
+    description:
+      name: cli_util
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.3+2"
+  code_builder:
+    dependency: transitive
+    description:
+      name: code_builder
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.2"
+  collection:
+    dependency: transitive
+    description:
+      name: collection
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.14.11"
+  convert:
+    dependency: transitive
+    description:
+      name: convert
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.2"
+  crypto:
+    dependency: transitive
+    description:
+      name: crypto
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.6"
+  csslib:
+    dependency: transitive
+    description:
+      name: csslib
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.14.5"
+  dart_style:
+    dependency: transitive
+    description:
+      name: dart_style
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.3"
+  fixnum:
+    dependency: transitive
+    description:
+      name: fixnum
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.10.8"
+  front_end:
+    dependency: transitive
+    description:
+      name: front_end
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.4"
+  glob:
+    dependency: transitive
+    description:
+      name: glob
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.7"
+  graphs:
+    dependency: transitive
+    description:
+      name: graphs
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.2+1"
+  html:
+    dependency: transitive
+    description:
+      name: html
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.13.3+3"
+  http:
+    dependency: transitive
+    description:
+      name: http
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.11.3+17"
+  http_multi_server:
+    dependency: transitive
+    description:
+      name: http_multi_server
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.5"
+  http_parser:
+    dependency: transitive
+    description:
+      name: http_parser
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "3.1.3"
+  io:
+    dependency: transitive
+    description:
+      name: io
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.3"
+  js:
+    dependency: transitive
+    description:
+      name: js
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.6.1+1"
+  json_annotation:
+    dependency: transitive
+    description:
+      name: json_annotation
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.0"
+  json_rpc_2:
+    dependency: transitive
+    description:
+      name: json_rpc_2
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.9"
+  kernel:
+    dependency: transitive
+    description:
+      name: kernel
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.3.4"
+  logging:
+    dependency: transitive
+    description:
+      name: logging
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.11.3+2"
+  matcher:
+    dependency: transitive
+    description:
+      name: matcher
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.12.3+1"
+  meta:
+    dependency: transitive
+    description:
+      name: meta
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.6"
+  mime:
+    dependency: transitive
+    description:
+      name: mime
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.9.6+2"
+  multi_server_socket:
+    dependency: transitive
+    description:
+      name: multi_server_socket
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.2"
+  node_preamble:
+    dependency: transitive
+    description:
+      name: node_preamble
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.4.4"
+  openapi:
+    dependency: "direct main"
+    description:
+      path: "../openapi-browser-client"
+      relative: true
+    source: path
+    version: "1.0.0"
+  package_config:
+    dependency: transitive
+    description:
+      name: package_config
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.5"
+  package_resolver:
+    dependency: transitive
+    description:
+      name: package_resolver
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.4"
+  path:
+    dependency: transitive
+    description:
+      name: path
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.6.2"
+  plugin:
+    dependency: transitive
+    description:
+      name: plugin
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.0+3"
+  pool:
+    dependency: transitive
+    description:
+      name: pool
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.6"
+  protobuf:
+    dependency: transitive
+    description:
+      name: protobuf
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.9.1"
+  pub_semver:
+    dependency: transitive
+    description:
+      name: pub_semver
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.4.2"
+  pubspec_parse:
+    dependency: transitive
+    description:
+      name: pubspec_parse
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.1.2+2"
+  quiver:
+    dependency: transitive
+    description:
+      name: quiver
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.0.0+1"
+  scratch_space:
+    dependency: transitive
+    description:
+      name: scratch_space
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.0.3+1"
+  shelf:
+    dependency: transitive
+    description:
+      name: shelf
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.7.3+3"
+  shelf_packages_handler:
+    dependency: transitive
+    description:
+      name: shelf_packages_handler
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.4"
+  shelf_static:
+    dependency: transitive
+    description:
+      name: shelf_static
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.8"
+  shelf_web_socket:
+    dependency: transitive
+    description:
+      name: shelf_web_socket
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.2+4"
+  source_map_stack_trace:
+    dependency: transitive
+    description:
+      name: source_map_stack_trace
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.5"
+  source_maps:
+    dependency: transitive
+    description:
+      name: source_maps
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.10.7"
+  source_span:
+    dependency: transitive
+    description:
+      name: source_span
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.4.1"
+  stack_trace:
+    dependency: transitive
+    description:
+      name: stack_trace
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.9.3"
+  stream_channel:
+    dependency: transitive
+    description:
+      name: stream_channel
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.6.8"
+  stream_transform:
+    dependency: transitive
+    description:
+      name: stream_transform
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.0.14+1"
+  string_scanner:
+    dependency: transitive
+    description:
+      name: string_scanner
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.4"
+  term_glyph:
+    dependency: transitive
+    description:
+      name: term_glyph
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.1"
+  test:
+    dependency: "direct main"
+    description:
+      name: test
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.3.0"
+  typed_data:
+    dependency: transitive
+    description:
+      name: typed_data
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.1.6"
+  utf:
+    dependency: transitive
+    description:
+      name: utf
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.9.0+5"
+  vm_service_client:
+    dependency: transitive
+    description:
+      name: vm_service_client
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.2.6"
+  watcher:
+    dependency: transitive
+    description:
+      name: watcher
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "0.9.7+10"
+  web_socket_channel:
+    dependency: transitive
+    description:
+      name: web_socket_channel
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "1.0.9"
+  yaml:
+    dependency: transitive
+    description:
+      name: yaml
+      url: "https://pub.dartlang.org"
+    source: hosted
+    version: "2.1.15"
+sdks:
+  dart: ">=2.0.0 <3.0.0"
diff --git a/samples/client/petstore/dart2/petstore/pubspec.yaml b/samples/client/petstore/dart2/petstore/pubspec.yaml
index cd9abef5a9f..c7ab5444867 100644
--- a/samples/client/petstore/dart2/petstore/pubspec.yaml
+++ b/samples/client/petstore/dart2/petstore/pubspec.yaml
@@ -6,6 +6,8 @@ environment:
 dependencies:
   openapi:
     path: ../openapi-browser-client
-  browser: any
+  test: ^1.3.0
 dev_dependencies:
-  guinness: '^0.1.17'
+  build_runner: ^0.10.1+1
+  build_test: ^0.10.3+1
+  build_web_compilers: ^0.4.2+2
-- 
GitLab


From 8118bf603841076066e8e820f0de7f3fb9860298 Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 11:28:17 +0800
Subject: [PATCH 06/16] supportDart2 option can now be passed through
 --additional-properties

---
 .../openapitools/codegen/languages/DartClientCodegen.java   | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
index 32a6338a10f..3ab3678ddf0 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/DartClientCodegen.java
@@ -28,6 +28,7 @@ import org.openapitools.codegen.SupportingFile;
 import org.openapitools.codegen.utils.ModelUtils;
 
 import io.swagger.v3.oas.models.media.*;
+import io.swagger.v3.parser.util.SchemaTypeUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -125,7 +126,7 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
         cliOptions.add(new CliOption(PUB_DESCRIPTION, "Description in generated pubspec"));
         cliOptions.add(new CliOption(USE_ENUM_EXTENSION, "Allow the 'x-enum-values' extension for enums"));
         cliOptions.add(new CliOption(CodegenConstants.SOURCE_FOLDER, "source folder for generated code"));
-        cliOptions.add(new CliOption(SUPPORT_DART2, "support dart2").defaultValue("false"));
+        cliOptions.add(CliOption.newBoolean(SUPPORT_DART2, "support dart2").defaultValue(Boolean.FALSE.toString()));
     }
 
     @Override
@@ -190,7 +191,8 @@ public class DartClientCodegen extends DefaultCodegen implements CodegenConfig {
         additionalProperties.put("apiDocPath", apiDocPath);
         additionalProperties.put("modelDocPath", modelDocPath);
 
-        if (Boolean.TRUE.equals(additionalProperties.get(SUPPORT_DART2))) {
+        final Object isSupportDart2 = additionalProperties.get(SUPPORT_DART2);
+        if (Boolean.TRUE.equals(isSupportDart2) || (isSupportDart2 instanceof String && Boolean.parseBoolean((String)isSupportDart2))) {
             embeddedTemplateDir = templateDir = "dart2";
         } else {
             supportingFiles.add(new SupportingFile("analysis_options.mustache", "", ".analysis_options"));
-- 
GitLab


From e928e227cf1d1a6a48bfce91e8e0e6ae2497a168 Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 11:30:07 +0800
Subject: [PATCH 07/16] Update petstore tests

---
 .../dart2/petstore/test/pet_test.dart         | 45 +++++++++++--------
 .../dart2/petstore/test/random_id.dart        |  7 +++
 .../dart2/petstore/test/store_test.dart       | 23 ++++++----
 .../petstore/dart2/petstore/test/tests.dart   | 23 ----------
 .../petstore/dart2/petstore/test/tests.html   | 14 ------
 .../dart2/petstore/test/user_test.dart        | 34 +++++++-------
 6 files changed, 66 insertions(+), 80 deletions(-)
 create mode 100644 samples/client/petstore/dart2/petstore/test/random_id.dart
 delete mode 100644 samples/client/petstore/dart2/petstore/test/tests.dart
 delete mode 100644 samples/client/petstore/dart2/petstore/test/tests.html

diff --git a/samples/client/petstore/dart2/petstore/test/pet_test.dart b/samples/client/petstore/dart2/petstore/test/pet_test.dart
index 213396f29cb..736ec378222 100644
--- a/samples/client/petstore/dart2/petstore/test/pet_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/pet_test.dart
@@ -1,40 +1,47 @@
-part of tests;
+@TestOn('browser')
 
-testPetApi() {
+import 'dart:async';
+
+import 'package:http/http.dart';
+import 'package:openapi/api.dart';
+import 'package:test/test.dart';
+
+import 'random_id.dart';
+
+void main() {
   var petApi = new PetApi();
 
-  describe('Pet API ', () {
-    it('adds a new pet and gets it by id', () async {
+  group('Pet API ', () {
+    test('adds a new pet and gets it by id', () async {
       var id = newId();
 
       await petApi.addPet(new Pet()..id = id);
       var pet = await petApi.getPetById(id);
-      expect(pet.id).toEqual(id);
+      expect(pet.id, equals(id));
     });
 
-    it('doesn\'t get non-existing pet by id', () {
-      expect(petApi.getPetById(newId()))
-          .toThrowWith(anInstanceOf: ApiException);
+    test('doesn\'t get non-existing pet by id', () {
+      expect(petApi.getPetById(newId()), throwsA(equals(TypeMatcher<ApiException>())));
     });
 
-    it('deletes existing pet by id', () async {
+    test('deletes existing pet by id', () async {
       var id = newId();
       await petApi.addPet(new Pet()..id = id);
       await petApi.deletePet(id, apiKey: 'special-key');
-      expect(petApi.getPetById(id)).toThrowWith(anInstanceOf: ApiException);
+      expect(petApi.getPetById(id), throwsA(equals(TypeMatcher<ApiException>())));
     });
 
-    it('updates pet with form', () async {
+    test('updates pet with form', () async {
       var id = newId();
       await petApi.addPet(new Pet()
         ..id = id
         ..name = 'Snowy');
       await petApi.updatePetWithForm(id, name: 'Doge', status: '');
       var pet = await petApi.getPetById(id);
-      expect(pet.name).toEqual('Doge');
+      expect(pet.name, equals('Doge'));
     });
 
-    it('updates existing pet', () async {
+    test('updates existing pet', () async {
       var id = newId();
       var name = 'Snowy';
 
@@ -43,10 +50,10 @@ testPetApi() {
         ..id = id
         ..name = name);
       var pet = await petApi.getPetById(id);
-      expect(pet.name).toEqual(name);
+      expect(pet.name, equals(name));
     });
 
-    it('finds pets by status', () async {
+    test('finds pets by status', () async {
       var id1 = newId();
       var id2 = newId();
       var id3 = newId();
@@ -65,13 +72,13 @@ testPetApi() {
       ]).then((_) async {
         var pets = await petApi.findPetsByStatus([status]);
         var petIds = pets.map((pet) => pet.id).toList();
-        expect(petIds).toContain(id1);
-        expect(petIds).toContain(id2);
-        expect(petIds).not.toContain(id3);
+        expect(petIds, contains(id1));
+        expect(petIds, contains(id2));
+        expect(petIds, isNot(contains(id3)));
       });
     });
 
-    it('uploads a pet image', () async {
+    test('uploads a pet image', () async {
       var id = newId();
       await petApi.addPet(new Pet()..id = id);
       var file = new MultipartFile.fromBytes('file', [104, 101, 108, 108, 111]);
diff --git a/samples/client/petstore/dart2/petstore/test/random_id.dart b/samples/client/petstore/dart2/petstore/test/random_id.dart
new file mode 100644
index 00000000000..0457428c7dd
--- /dev/null
+++ b/samples/client/petstore/dart2/petstore/test/random_id.dart
@@ -0,0 +1,7 @@
+import 'dart:math';
+
+final _random = new Random();
+
+int newId() {
+  return _random.nextInt(999999);
+}
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/petstore/test/store_test.dart b/samples/client/petstore/dart2/petstore/test/store_test.dart
index 39d9cecfac7..e382beb3460 100644
--- a/samples/client/petstore/dart2/petstore/test/store_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/store_test.dart
@@ -1,28 +1,33 @@
-part of tests;
+@TestOn('browser')
 
-testStoreApi() {
+import 'package:openapi/api.dart';
+import 'package:test/test.dart';
+
+import 'random_id.dart';
+
+void main() {
   var storeApi = new StoreApi();
 
-  describe('Store API ', () {
-    it('places an order and gets it by id', () async {
+  group('Store API ', () {
+    test('places an order and gets it by id', () async {
       var id = newId();
 
       await storeApi.placeOrder(new Order()..id = id);
       var order = await storeApi.getOrderById(id);
-      expect(order.id).toEqual(id);
+      expect(order.id, equals(id));
     });
 
-    it('deletes an order', () async {
+    test('deletes an order', () async {
       var id = newId();
 
       await storeApi.placeOrder(new Order()..id = id);
       await storeApi.deleteOrder(id.toString());
-      expect(storeApi.getOrderById(id)).toThrowWith(anInstanceOf: ApiException);
+      expect(storeApi.getOrderById(id), throwsA(equals(TypeMatcher<ApiException>())));
     });
 
-    it('gets the store inventory', () async {
+    test('gets the store inventory', () async {
       Map<String, int> inventory = await storeApi.getInventory();
-      expect(inventory.length).not.toBe(0);
+      expect(inventory.length, isNot(equals(0)));
     });
   });
 }
diff --git a/samples/client/petstore/dart2/petstore/test/tests.dart b/samples/client/petstore/dart2/petstore/test/tests.dart
deleted file mode 100644
index cea11e15a9c..00000000000
--- a/samples/client/petstore/dart2/petstore/test/tests.dart
+++ /dev/null
@@ -1,23 +0,0 @@
-library tests;
-
-import 'dart:async';
-import 'dart:math';
-import 'package:http/http.dart';
-import 'package:guinness/guinness.dart';
-import 'package:openapi/api.dart';
-
-part 'pet_test.dart';
-part 'store_test.dart';
-part 'user_test.dart';
-
-final random = new Random();
-
-int newId() {
-  return random.nextInt(999999);
-}
-
-main() {
-  testPetApi();
-  testStoreApi();
-  testUserApi();
-}
diff --git a/samples/client/petstore/dart2/petstore/test/tests.html b/samples/client/petstore/dart2/petstore/test/tests.html
deleted file mode 100644
index e3796c5fcfe..00000000000
--- a/samples/client/petstore/dart2/petstore/test/tests.html
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-
-<html>
-<head>
-    <meta charset="utf-8">
-    <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Unit Test Results</title>
-</head>
-
-<body>
-<script type="application/dart" src="tests.dart"></script>
-<script src="packages/browser/dart.js"></script>
-</body>
-</html>
\ No newline at end of file
diff --git a/samples/client/petstore/dart2/petstore/test/user_test.dart b/samples/client/petstore/dart2/petstore/test/user_test.dart
index 7188a1d25ea..e9cb9977f56 100644
--- a/samples/client/petstore/dart2/petstore/test/user_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/user_test.dart
@@ -1,20 +1,25 @@
-part of tests;
+@TestOn('browser')
 
-testUserApi() {
+import 'package:openapi/api.dart';
+import 'package:test/test.dart';
+
+import 'random_id.dart';
+
+void main() {
   var userApi = new UserApi();
 
-  describe('User API ', () {
-    it('creates a user', () async {
+  group('User API ', () {
+    test('creates a user', () async {
       var id = newId();
       var username = 'Mally45';
       await userApi.createUser(new User()
         ..id = id
         ..username = username);
       var user = await userApi.getUserByName(username);
-      expect(user.id).toEqual(id);
+      expect(user.id, equals(id));
     });
 
-    it('creates users with list input', () async {
+    test('creates users with list input', () async {
       var firstId = newId();
       var joe = 'Joe';
 
@@ -33,11 +38,11 @@ testUserApi() {
       await userApi.createUsersWithListInput(users);
       var firstUser = await userApi.getUserByName(joe);
       var secondUser = await userApi.getUserByName(sally);
-      expect(firstUser.id).toEqual(firstId);
-      expect(secondUser.id).toEqual(secondId);
+      expect(firstUser.id, equals(firstId));
+      expect(secondUser.id, equals(secondId));
     });
 
-    it('updates a user', () async {
+    test('updates a user', () async {
       var username = 'Arkjam89';
       var email = 'test@example.com';
       var user = new User()
@@ -48,20 +53,19 @@ testUserApi() {
       user.email = email;
       await userApi.updateUser(username, user);
       var foundUser = await userApi.getUserByName(username);
-      expect(foundUser.email).toEqual(email);
+      expect(foundUser.email, equals(email));
     });
 
-    it('deletes a user', () async {
+    test('deletes a user', () async {
       var username = 'Riddlem325';
       await userApi.createUser(new User()
         ..id = newId()
         ..username = username);
       await userApi.deleteUser(username);
-      expect(userApi.getUserByName(username))
-          .toThrowWith(anInstanceOf: ApiException);
+      expect(userApi.getUserByName(username), throwsA(TypeMatcher<ApiException>()));
     });
 
-    it('logs a user in', () async {
+    test('logs a user in', () async {
       var username = 'sgarad625';
       var password = 'lokimoki1';
       var user = new User()
@@ -71,7 +75,7 @@ testUserApi() {
 
       await userApi.createUser(user);
       var result = await userApi.loginUser(username, password);
-      expect(result).toContain('logged in user session:');
+      expect(result, contains('logged in user session:'));
     });
   });
 }
-- 
GitLab


From 292654c5747d8162859d924fe328001d33767ddd Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 12:42:39 +0800
Subject: [PATCH 08/16] Update dart2-petstore.sh

---
 bin/dart2-petstore.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bin/dart2-petstore.sh b/bin/dart2-petstore.sh
index 8c415b9b1bd..7160d1c38b0 100755
--- a/bin/dart2-petstore.sh
+++ b/bin/dart2-petstore.sh
@@ -32,7 +32,7 @@ export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/
 ags="generate -t modules/openapi-generator/src/main/resources/dart -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/openapi -DhideGenerationTimestamp=true -DbrowserClient=false --additional-properties supportDart2=true $@"
 
 # then options to generate the library for vm would be:
-#ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart/openapi_vm -DbrowserClient=false -DpubName=openapi_vm $@"
+#ags="generate -i modules/openapi-generator/src/test/resources/2_0/petstore.yaml -g dart -o samples/client/petstore/dart2/openapi_vm -DbrowserClient=false -DpubName=openapi_vm $@"
 java $JAVA_OPTS -jar $executable $ags
 
 # Generate browserClient
-- 
GitLab


From 8be29548e589b1af0fa84071b6d9f03370237c1f Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 14:09:50 +0800
Subject: [PATCH 09/16] Running tests on Dart VM

---
 samples/client/petstore/dart2/openapi/lib/api_client.dart     | 4 ++--
 .../petstore/dart2/openapi/lib/auth/http_basic_auth.dart      | 4 ++--
 samples/client/petstore/dart2/petstore/pubspec.lock           | 2 +-
 samples/client/petstore/dart2/petstore/pubspec.yaml           | 2 +-
 samples/client/petstore/dart2/petstore/test/pet_test.dart     | 2 --
 samples/client/petstore/dart2/petstore/test/store_test.dart   | 2 --
 samples/client/petstore/dart2/petstore/test/user_test.dart    | 2 --
 7 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/samples/client/petstore/dart2/openapi/lib/api_client.dart b/samples/client/petstore/dart2/openapi/lib/api_client.dart
index db4116dd96d..042deb946ae 100644
--- a/samples/client/petstore/dart2/openapi/lib/api_client.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api_client.dart
@@ -78,7 +78,7 @@ class ApiClient {
 
     if (targetType == 'String') return json;
 
-    var decodedJson = JSON.decode(json);
+    var decodedJson = jsonDecode(json);
     return _deserialize(decodedJson, targetType);
   }
 
@@ -87,7 +87,7 @@ class ApiClient {
     if (obj == null) {
       serialized = '';
     } else {
-      serialized = JSON.encode(obj);
+      serialized = json.encode(obj);
     }
     return serialized;
   }
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
index 4e77ddcf6e6..6342d886689 100644
--- a/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
+++ b/samples/client/petstore/dart2/openapi/lib/auth/http_basic_auth.dart
@@ -8,7 +8,7 @@ class HttpBasicAuth implements Authentication {
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
     String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
-    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+    headerParams["Authorization"] = "Basic " + base64.encode(utf8.encode(str));
   }
 
-}
\ No newline at end of file
+}
diff --git a/samples/client/petstore/dart2/petstore/pubspec.lock b/samples/client/petstore/dart2/petstore/pubspec.lock
index ef8517fab6a..f077e1d4423 100644
--- a/samples/client/petstore/dart2/petstore/pubspec.lock
+++ b/samples/client/petstore/dart2/petstore/pubspec.lock
@@ -305,7 +305,7 @@ packages:
   openapi:
     dependency: "direct main"
     description:
-      path: "../openapi-browser-client"
+      path: "../openapi"
       relative: true
     source: path
     version: "1.0.0"
diff --git a/samples/client/petstore/dart2/petstore/pubspec.yaml b/samples/client/petstore/dart2/petstore/pubspec.yaml
index c7ab5444867..d84c7ac3202 100644
--- a/samples/client/petstore/dart2/petstore/pubspec.yaml
+++ b/samples/client/petstore/dart2/petstore/pubspec.yaml
@@ -5,7 +5,7 @@ environment:
   sdk: '>=2.0.0 <3.0.0'
 dependencies:
   openapi:
-    path: ../openapi-browser-client
+    path: ../openapi
   test: ^1.3.0
 dev_dependencies:
   build_runner: ^0.10.1+1
diff --git a/samples/client/petstore/dart2/petstore/test/pet_test.dart b/samples/client/petstore/dart2/petstore/test/pet_test.dart
index 736ec378222..866e621657e 100644
--- a/samples/client/petstore/dart2/petstore/test/pet_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/pet_test.dart
@@ -1,5 +1,3 @@
-@TestOn('browser')
-
 import 'dart:async';
 
 import 'package:http/http.dart';
diff --git a/samples/client/petstore/dart2/petstore/test/store_test.dart b/samples/client/petstore/dart2/petstore/test/store_test.dart
index e382beb3460..b6ebc8b9b59 100644
--- a/samples/client/petstore/dart2/petstore/test/store_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/store_test.dart
@@ -1,5 +1,3 @@
-@TestOn('browser')
-
 import 'package:openapi/api.dart';
 import 'package:test/test.dart';
 
diff --git a/samples/client/petstore/dart2/petstore/test/user_test.dart b/samples/client/petstore/dart2/petstore/test/user_test.dart
index e9cb9977f56..909c4af13e5 100644
--- a/samples/client/petstore/dart2/petstore/test/user_test.dart
+++ b/samples/client/petstore/dart2/petstore/test/user_test.dart
@@ -1,5 +1,3 @@
-@TestOn('browser')
-
 import 'package:openapi/api.dart';
 import 'package:test/test.dart';
 
-- 
GitLab


From 37d10cf0a961023c2186c8ec36a62f64c379db8e Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 17:11:43 +0800
Subject: [PATCH 10/16] Fixed JSON deserialization bugs

---
 .../openapi-generator/src/main/resources/dart2/class.mustache | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/modules/openapi-generator/src/main/resources/dart2/class.mustache b/modules/openapi-generator/src/main/resources/dart2/class.mustache
index c13f51c33d5..43c1c0725ce 100644
--- a/modules/openapi-generator/src/main/resources/dart2/class.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/class.mustache
@@ -1,7 +1,7 @@
 class {{classname}} {
   {{#vars}}
   {{#description}}/* {{{description}}} */{{/description}}
-  {{{dataType}}} {{name}};
+  {{{dataType}}} {{name}} = {{{defaultValue}}};
   {{#allowableValues}}
   {{#min}} // range from {{min}} to {{max}}{{/min}}//{{^min}}enum {{name}}Enum { {{#values}} {{.}}, {{/values}} };{{/min}}{
   {{/allowableValues}}
@@ -39,7 +39,7 @@ class {{classname}} {
     {{/complexType}}
     {{^complexType}}
       {{#isListContainer}}
-    {{name}} = (json['{{baseName}}'] as List).map((item) => item as {{items.datatype}}).toList();
+    {{name}} = ((json['{{baseName}}'] ?? []) as List).map((item) => item as {{items.datatype}}).toList();
       {{/isListContainer}}
       {{^isListContainer}}
     {{name}} = json['{{baseName}}'];
-- 
GitLab


From 35d9ccafc6935cc4588b395a3506aeca35b26bbd Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 17:18:49 +0800
Subject: [PATCH 11/16] Fixed missing initialization of postBody

---
 modules/openapi-generator/src/main/resources/dart2/api.mustache | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/openapi-generator/src/main/resources/dart2/api.mustache b/modules/openapi-generator/src/main/resources/dart2/api.mustache
index 18a70be92ab..76797fa2ddc 100644
--- a/modules/openapi-generator/src/main/resources/dart2/api.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/api.mustache
@@ -13,7 +13,7 @@ class {{classname}} {
   ///
   /// {{notes}}
   {{#returnType}}Future<{{{returnType}}}> {{/returnType}}{{^returnType}}Future {{/returnType}}{{nickname}}({{#allParams}}{{#required}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}}{{#hasOptionalParams}}{ {{#allParams}}{{^required}}{{{dataType}}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/required}}{{/allParams}} }{{/hasOptionalParams}}) async {
-    Object postBody;
+    Object postBody{{#bodyParam}} = {{paramName}}{{/bodyParam}};
 
     // verify required params are set
     {{#allParams}}
-- 
GitLab


From 9ae0f512e2dcba3f1cde5ea44cec2639f01d45ef Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 17:35:26 +0800
Subject: [PATCH 12/16] Run bin/dart2-petstore.sh to regenerate libraries

---
 .../flutter_petstore/openapi/lib/api.dart     |  2 +-
 .../openapi/lib/api/pet_api.dart              | 12 +++---
 .../openapi/lib/api/store_api.dart            |  6 +--
 .../openapi/lib/api/user_api.dart             |  8 ++--
 .../openapi/lib/api_client.dart               | 40 +++++++++----------
 .../openapi/lib/api_exception.dart            |  8 ++--
 .../openapi/lib/api_helper.dart               |  6 +--
 .../openapi/lib/auth/api_key_auth.dart        |  2 +-
 .../openapi/lib/auth/http_basic_auth.dart     |  4 +-
 .../openapi/lib/auth/oauth.dart               |  3 +-
 .../openapi/lib/model/pet.dart                |  2 +-
 .../flutter_petstore/openapi/pubspec.yaml     |  2 -
 .../dart2/openapi-browser-client/lib/api.dart |  2 +-
 .../lib/api/pet_api.dart                      | 12 +++---
 .../lib/api/store_api.dart                    |  6 +--
 .../lib/api/user_api.dart                     |  8 ++--
 .../lib/api_client.dart                       | 40 +++++++++----------
 .../lib/api_exception.dart                    |  8 ++--
 .../lib/api_helper.dart                       |  6 +--
 .../lib/auth/api_key_auth.dart                |  2 +-
 .../lib/auth/http_basic_auth.dart             |  4 +-
 .../lib/auth/oauth.dart                       |  3 +-
 .../openapi-browser-client/lib/model/pet.dart |  2 +-
 .../dart2/openapi-browser-client/pubspec.yaml |  2 -
 .../petstore/dart2/openapi/lib/api.dart       |  2 +-
 .../dart2/openapi/lib/api/pet_api.dart        | 12 +++---
 .../dart2/openapi/lib/api/store_api.dart      |  6 +--
 .../dart2/openapi/lib/api/user_api.dart       |  8 ++--
 .../dart2/openapi/lib/api_client.dart         | 36 ++++++++---------
 .../dart2/openapi/lib/api_exception.dart      |  8 ++--
 .../dart2/openapi/lib/api_helper.dart         |  6 +--
 .../dart2/openapi/lib/auth/api_key_auth.dart  |  2 +-
 .../dart2/openapi/lib/auth/oauth.dart         |  3 +-
 .../petstore/dart2/openapi/lib/model/pet.dart |  2 +-
 .../petstore/dart2/openapi/pubspec.yaml       |  2 -
 35 files changed, 134 insertions(+), 143 deletions(-)

diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
index 9a64a5342b4..69c3ecd2e15 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api.dart
@@ -24,4 +24,4 @@ part 'model/tag.dart';
 part 'model/user.dart';
 
 
-ApiClient defaultApiClient = new ApiClient();
+ApiClient defaultApiClient = ApiClient();
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
index 4134e018386..8e6c815ec2b 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/pet_api.dart
@@ -60,7 +60,7 @@ class PetApi {
   ///
   /// 
   Future deletePet(int petId, { String apiKey }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -110,7 +110,7 @@ class PetApi {
   ///
   /// Multiple status values can be provided with comma separated strings
   Future<List<Pet>> findPetsByStatus(List<String> status) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(status == null) {
@@ -161,7 +161,7 @@ class PetApi {
   ///
   /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
   Future<List<Pet>> findPetsByTags(List<String> tags) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(tags == null) {
@@ -212,7 +212,7 @@ class PetApi {
   ///
   /// Returns a single pet
   Future<Pet> getPetById(int petId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -311,7 +311,7 @@ class PetApi {
   ///
   /// 
   Future updatePetWithForm(int petId, { String name, String status }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -372,7 +372,7 @@ class PetApi {
   ///
   /// 
   Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
index f2a48f2d4da..38fe10d4450 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/store_api.dart
@@ -11,7 +11,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
   Future deleteOrder(String orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
@@ -60,7 +60,7 @@ class StoreApi {
   ///
   /// Returns a map of status codes to quantities
   Future<Map<String, int>> getInventory() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
@@ -108,7 +108,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
   Future<Order> getOrderById(int orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
index cf8ef6bf800..9d3eb116e61 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api/user_api.dart
@@ -158,7 +158,7 @@ class UserApi {
   ///
   /// This can only be done by the logged in user.
   Future deleteUser(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -207,7 +207,7 @@ class UserApi {
   ///
   /// 
   Future<User> getUserByName(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -257,7 +257,7 @@ class UserApi {
   ///
   /// 
   Future<String> loginUser(String username, String password) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -312,7 +312,7 @@ class UserApi {
   ///
   /// 
   Future logoutUser() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
index db4116dd96d..f1e49792f90 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_client.dart
@@ -10,18 +10,18 @@ class QueryParam {
 class ApiClient {
 
   String basePath;
-  var client = new Client();
+  var client = Client();
 
   Map<String, String> _defaultHeaderMap = {};
   Map<String, Authentication> _authentications = {};
 
-  final _RegList = new RegExp(r'^List<(.*)>$');
-  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+  final _regList = RegExp(r'^List<(.*)>$');
+  final _regMap = RegExp(r'^Map<String,(.*)>$');
 
   ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
     // Setup authentications (key: authentication name, value: authentication).
-    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
-    _authentications['petstore_auth'] = new OAuth();
+    _authentications['api_key'] = ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = OAuth();
   }
 
   void addDefaultHeader(String key, String value) {
@@ -40,36 +40,36 @@ class ApiClient {
         case 'double':
           return value is double ? value : double.parse('$value');
         case 'ApiResponse':
-          return new ApiResponse.fromJson(value);
+          return ApiResponse.fromJson(value);
         case 'Category':
-          return new Category.fromJson(value);
+          return Category.fromJson(value);
         case 'Order':
-          return new Order.fromJson(value);
+          return Order.fromJson(value);
         case 'Pet':
-          return new Pet.fromJson(value);
+          return Pet.fromJson(value);
         case 'Tag':
-          return new Tag.fromJson(value);
+          return Tag.fromJson(value);
         case 'User':
-          return new User.fromJson(value);
+          return User.fromJson(value);
         default:
           {
             Match match;
             if (value is List &&
-                (match = _RegList.firstMatch(targetType)) != null) {
+                (match = _regList.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
               return value.map((v) => _deserialize(v, newTargetType)).toList();
             } else if (value is Map &&
-                (match = _RegMap.firstMatch(targetType)) != null) {
+                (match = _regMap.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
-              return new Map.fromIterables(value.keys,
+              return Map.fromIterables(value.keys,
                   value.values.map((v) => _deserialize(v, newTargetType)));
             }
           }
       }
     } catch (e, stack) {
-      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+      throw ApiException.withInner(500, 'Exception during deserialization.', e, stack);
     }
-    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+    throw ApiException(500, 'Could not find a suitable class for deserialization');
   }
 
   dynamic deserialize(String json, String targetType) {
@@ -78,7 +78,7 @@ class ApiClient {
 
     if (targetType == 'String') return json;
 
-    var decodedJson = JSON.decode(json);
+    var decodedJson = jsonDecode(json);
     return _deserialize(decodedJson, targetType);
   }
 
@@ -87,7 +87,7 @@ class ApiClient {
     if (obj == null) {
       serialized = '';
     } else {
-      serialized = JSON.encode(obj);
+      serialized = json.encode(obj);
     }
     return serialized;
   }
@@ -116,7 +116,7 @@ class ApiClient {
     headerParams['Content-Type'] = contentType;
 
     if(body is MultipartRequest) {
-      var request = new MultipartRequest(method, Uri.parse(url));
+      var request = MultipartRequest(method, Uri.parse(url));
       request.fields.addAll(body.fields);
       request.files.addAll(body.files);
       request.headers.addAll(body.headers);
@@ -145,7 +145,7 @@ class ApiClient {
   void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
     authNames.forEach((authName) {
       Authentication auth = _authentications[authName];
-      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      if (auth == null) throw ArgumentError("Authentication undefined: " + authName);
       auth.applyToParams(queryParams, headerParams);
     });
   }
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
index f188fd125a4..668abe2c96b 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_exception.dart
@@ -2,9 +2,9 @@ part of openapi.api;
 
 class ApiException implements Exception {
   int code = 0;
-  String message = null;
-  Exception innerException = null;
-  StackTrace stackTrace = null;
+  String message;
+  Exception innerException;
+  StackTrace stackTrace;
 
   ApiException(this.code, this.message);
 
@@ -17,7 +17,7 @@ class ApiException implements Exception {
       return "ApiException $code: $message";
     }
 
-    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+    return "ApiException $code: $message (Inner exception: $innerException)\n\n" +
         stackTrace.toString();
   }
 }
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
index 79af4521d5b..a516a68d264 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/api_helper.dart
@@ -11,7 +11,7 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
   if (name == null || name.isEmpty || value == null) return params;
 
   if (value is! List) {
-    params.add(new QueryParam(name, parameterToString(value)));
+    params.add(QueryParam(name, parameterToString(value)));
     return params;
   }
 
@@ -23,12 +23,12 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
                      : collectionFormat; // default: csv
 
   if (collectionFormat == "multi") {
-    return values.map((v) => new QueryParam(name, parameterToString(v)));
+    return values.map((v) => QueryParam(name, parameterToString(v)));
   }
 
   String delimiter = _delimiters[collectionFormat] ?? ",";
 
-  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  params.add(QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
   return params;
 }
 
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
index f9617f7ae4d..8caf6ab5eba 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/api_key_auth.dart
@@ -19,7 +19,7 @@ class ApiKeyAuth implements Authentication {
     }
 
     if (location == 'query' && value != null) {
-      queryParams.add(new QueryParam(paramName, value));
+      queryParams.add(QueryParam(paramName, value));
     } else if (location == 'header' && value != null) {
       headerParams[paramName] = value;
     }
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
index 4e77ddcf6e6..6342d886689 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/http_basic_auth.dart
@@ -8,7 +8,7 @@ class HttpBasicAuth implements Authentication {
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
     String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
-    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+    headerParams["Authorization"] = "Basic " + base64.encode(utf8.encode(str));
   }
 
-}
\ No newline at end of file
+}
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
index 13bfd799743..aa08e5cdb4d 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/auth/oauth.dart
@@ -3,8 +3,7 @@ part of openapi.api;
 class OAuth implements Authentication {
   String accessToken;
 
-  OAuth({this.accessToken}) {
-  }
+  OAuth({this.accessToken});
 
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
index 4d2f77a1a5a..da9de49b678 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/lib/model/pet.dart
@@ -26,7 +26,7 @@ class Pet {
     id = json['id'];
     category = new Category.fromJson(json['category']);
     name = json['name'];
-    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    photoUrls = ((json['photoUrls'] ?? []) as List).map((item) => item as String).toList();
     tags = Tag.listFromJson(json['tags']);
     status = json['status'];
   }
diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
index 9ccf0e524ad..d54efb46a2e 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
@@ -1,7 +1,5 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
-environment:
-  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
index 84476e0626a..4e43a1c2083 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api.dart
@@ -25,4 +25,4 @@ part 'model/tag.dart';
 part 'model/user.dart';
 
 
-ApiClient defaultApiClient = new ApiClient();
+ApiClient defaultApiClient = ApiClient();
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
index 4134e018386..8e6c815ec2b 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/pet_api.dart
@@ -60,7 +60,7 @@ class PetApi {
   ///
   /// 
   Future deletePet(int petId, { String apiKey }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -110,7 +110,7 @@ class PetApi {
   ///
   /// Multiple status values can be provided with comma separated strings
   Future<List<Pet>> findPetsByStatus(List<String> status) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(status == null) {
@@ -161,7 +161,7 @@ class PetApi {
   ///
   /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
   Future<List<Pet>> findPetsByTags(List<String> tags) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(tags == null) {
@@ -212,7 +212,7 @@ class PetApi {
   ///
   /// Returns a single pet
   Future<Pet> getPetById(int petId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -311,7 +311,7 @@ class PetApi {
   ///
   /// 
   Future updatePetWithForm(int petId, { String name, String status }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -372,7 +372,7 @@ class PetApi {
   ///
   /// 
   Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
index f2a48f2d4da..38fe10d4450 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/store_api.dart
@@ -11,7 +11,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
   Future deleteOrder(String orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
@@ -60,7 +60,7 @@ class StoreApi {
   ///
   /// Returns a map of status codes to quantities
   Future<Map<String, int>> getInventory() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
@@ -108,7 +108,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
   Future<Order> getOrderById(int orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
index cf8ef6bf800..9d3eb116e61 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api/user_api.dart
@@ -158,7 +158,7 @@ class UserApi {
   ///
   /// This can only be done by the logged in user.
   Future deleteUser(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -207,7 +207,7 @@ class UserApi {
   ///
   /// 
   Future<User> getUserByName(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -257,7 +257,7 @@ class UserApi {
   ///
   /// 
   Future<String> loginUser(String username, String password) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -312,7 +312,7 @@ class UserApi {
   ///
   /// 
   Future logoutUser() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
index 7cca5bef5f2..2ffa4e695a5 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_client.dart
@@ -10,18 +10,18 @@ class QueryParam {
 class ApiClient {
 
   String basePath;
-  var client = new BrowserClient();
+  var client = BrowserClient();
 
   Map<String, String> _defaultHeaderMap = {};
   Map<String, Authentication> _authentications = {};
 
-  final _RegList = new RegExp(r'^List<(.*)>$');
-  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+  final _regList = RegExp(r'^List<(.*)>$');
+  final _regMap = RegExp(r'^Map<String,(.*)>$');
 
   ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
     // Setup authentications (key: authentication name, value: authentication).
-    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
-    _authentications['petstore_auth'] = new OAuth();
+    _authentications['api_key'] = ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = OAuth();
   }
 
   void addDefaultHeader(String key, String value) {
@@ -40,36 +40,36 @@ class ApiClient {
         case 'double':
           return value is double ? value : double.parse('$value');
         case 'ApiResponse':
-          return new ApiResponse.fromJson(value);
+          return ApiResponse.fromJson(value);
         case 'Category':
-          return new Category.fromJson(value);
+          return Category.fromJson(value);
         case 'Order':
-          return new Order.fromJson(value);
+          return Order.fromJson(value);
         case 'Pet':
-          return new Pet.fromJson(value);
+          return Pet.fromJson(value);
         case 'Tag':
-          return new Tag.fromJson(value);
+          return Tag.fromJson(value);
         case 'User':
-          return new User.fromJson(value);
+          return User.fromJson(value);
         default:
           {
             Match match;
             if (value is List &&
-                (match = _RegList.firstMatch(targetType)) != null) {
+                (match = _regList.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
               return value.map((v) => _deserialize(v, newTargetType)).toList();
             } else if (value is Map &&
-                (match = _RegMap.firstMatch(targetType)) != null) {
+                (match = _regMap.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
-              return new Map.fromIterables(value.keys,
+              return Map.fromIterables(value.keys,
                   value.values.map((v) => _deserialize(v, newTargetType)));
             }
           }
       }
     } catch (e, stack) {
-      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+      throw ApiException.withInner(500, 'Exception during deserialization.', e, stack);
     }
-    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+    throw ApiException(500, 'Could not find a suitable class for deserialization');
   }
 
   dynamic deserialize(String json, String targetType) {
@@ -78,7 +78,7 @@ class ApiClient {
 
     if (targetType == 'String') return json;
 
-    var decodedJson = JSON.decode(json);
+    var decodedJson = jsonDecode(json);
     return _deserialize(decodedJson, targetType);
   }
 
@@ -87,7 +87,7 @@ class ApiClient {
     if (obj == null) {
       serialized = '';
     } else {
-      serialized = JSON.encode(obj);
+      serialized = json.encode(obj);
     }
     return serialized;
   }
@@ -116,7 +116,7 @@ class ApiClient {
     headerParams['Content-Type'] = contentType;
 
     if(body is MultipartRequest) {
-      var request = new MultipartRequest(method, Uri.parse(url));
+      var request = MultipartRequest(method, Uri.parse(url));
       request.fields.addAll(body.fields);
       request.files.addAll(body.files);
       request.headers.addAll(body.headers);
@@ -145,7 +145,7 @@ class ApiClient {
   void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
     authNames.forEach((authName) {
       Authentication auth = _authentications[authName];
-      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      if (auth == null) throw ArgumentError("Authentication undefined: " + authName);
       auth.applyToParams(queryParams, headerParams);
     });
   }
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
index f188fd125a4..668abe2c96b 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_exception.dart
@@ -2,9 +2,9 @@ part of openapi.api;
 
 class ApiException implements Exception {
   int code = 0;
-  String message = null;
-  Exception innerException = null;
-  StackTrace stackTrace = null;
+  String message;
+  Exception innerException;
+  StackTrace stackTrace;
 
   ApiException(this.code, this.message);
 
@@ -17,7 +17,7 @@ class ApiException implements Exception {
       return "ApiException $code: $message";
     }
 
-    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+    return "ApiException $code: $message (Inner exception: $innerException)\n\n" +
         stackTrace.toString();
   }
 }
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
index 79af4521d5b..a516a68d264 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/api_helper.dart
@@ -11,7 +11,7 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
   if (name == null || name.isEmpty || value == null) return params;
 
   if (value is! List) {
-    params.add(new QueryParam(name, parameterToString(value)));
+    params.add(QueryParam(name, parameterToString(value)));
     return params;
   }
 
@@ -23,12 +23,12 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
                      : collectionFormat; // default: csv
 
   if (collectionFormat == "multi") {
-    return values.map((v) => new QueryParam(name, parameterToString(v)));
+    return values.map((v) => QueryParam(name, parameterToString(v)));
   }
 
   String delimiter = _delimiters[collectionFormat] ?? ",";
 
-  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  params.add(QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
   return params;
 }
 
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
index f9617f7ae4d..8caf6ab5eba 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/api_key_auth.dart
@@ -19,7 +19,7 @@ class ApiKeyAuth implements Authentication {
     }
 
     if (location == 'query' && value != null) {
-      queryParams.add(new QueryParam(paramName, value));
+      queryParams.add(QueryParam(paramName, value));
     } else if (location == 'header' && value != null) {
       headerParams[paramName] = value;
     }
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
index 4e77ddcf6e6..6342d886689 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/http_basic_auth.dart
@@ -8,7 +8,7 @@ class HttpBasicAuth implements Authentication {
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
     String str = (username == null ? "" : username) + ":" + (password == null ? "" : password);
-    headerParams["Authorization"] = "Basic " + BASE64.encode(UTF8.encode(str));
+    headerParams["Authorization"] = "Basic " + base64.encode(utf8.encode(str));
   }
 
-}
\ No newline at end of file
+}
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
index 13bfd799743..aa08e5cdb4d 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/auth/oauth.dart
@@ -3,8 +3,7 @@ part of openapi.api;
 class OAuth implements Authentication {
   String accessToken;
 
-  OAuth({this.accessToken}) {
-  }
+  OAuth({this.accessToken});
 
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
diff --git a/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart b/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
index 4d2f77a1a5a..da9de49b678 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
+++ b/samples/client/petstore/dart2/openapi-browser-client/lib/model/pet.dart
@@ -26,7 +26,7 @@ class Pet {
     id = json['id'];
     category = new Category.fromJson(json['category']);
     name = json['name'];
-    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    photoUrls = ((json['photoUrls'] ?? []) as List).map((item) => item as String).toList();
     tags = Tag.listFromJson(json['tags']);
     status = json['status'];
   }
diff --git a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
index 9ccf0e524ad..d54efb46a2e 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
@@ -1,7 +1,5 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
-environment:
-  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi/lib/api.dart b/samples/client/petstore/dart2/openapi/lib/api.dart
index 9a64a5342b4..69c3ecd2e15 100644
--- a/samples/client/petstore/dart2/openapi/lib/api.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api.dart
@@ -24,4 +24,4 @@ part 'model/tag.dart';
 part 'model/user.dart';
 
 
-ApiClient defaultApiClient = new ApiClient();
+ApiClient defaultApiClient = ApiClient();
diff --git a/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart b/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
index 4134e018386..8e6c815ec2b 100644
--- a/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api/pet_api.dart
@@ -60,7 +60,7 @@ class PetApi {
   ///
   /// 
   Future deletePet(int petId, { String apiKey }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -110,7 +110,7 @@ class PetApi {
   ///
   /// Multiple status values can be provided with comma separated strings
   Future<List<Pet>> findPetsByStatus(List<String> status) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(status == null) {
@@ -161,7 +161,7 @@ class PetApi {
   ///
   /// Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
   Future<List<Pet>> findPetsByTags(List<String> tags) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(tags == null) {
@@ -212,7 +212,7 @@ class PetApi {
   ///
   /// Returns a single pet
   Future<Pet> getPetById(int petId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -311,7 +311,7 @@ class PetApi {
   ///
   /// 
   Future updatePetWithForm(int petId, { String name, String status }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
@@ -372,7 +372,7 @@ class PetApi {
   ///
   /// 
   Future<ApiResponse> uploadFile(int petId, { String additionalMetadata, MultipartFile file }) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(petId == null) {
diff --git a/samples/client/petstore/dart2/openapi/lib/api/store_api.dart b/samples/client/petstore/dart2/openapi/lib/api/store_api.dart
index f2a48f2d4da..38fe10d4450 100644
--- a/samples/client/petstore/dart2/openapi/lib/api/store_api.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api/store_api.dart
@@ -11,7 +11,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt; 1000. Anything above 1000 or nonintegers will generate API errors
   Future deleteOrder(String orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
@@ -60,7 +60,7 @@ class StoreApi {
   ///
   /// Returns a map of status codes to quantities
   Future<Map<String, int>> getInventory() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
@@ -108,7 +108,7 @@ class StoreApi {
   ///
   /// For valid response try integer IDs with value &lt;&#x3D; 5 or &gt; 10. Other values will generated exceptions
   Future<Order> getOrderById(int orderId) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(orderId == null) {
diff --git a/samples/client/petstore/dart2/openapi/lib/api/user_api.dart b/samples/client/petstore/dart2/openapi/lib/api/user_api.dart
index cf8ef6bf800..9d3eb116e61 100644
--- a/samples/client/petstore/dart2/openapi/lib/api/user_api.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api/user_api.dart
@@ -158,7 +158,7 @@ class UserApi {
   ///
   /// This can only be done by the logged in user.
   Future deleteUser(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -207,7 +207,7 @@ class UserApi {
   ///
   /// 
   Future<User> getUserByName(String username) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -257,7 +257,7 @@ class UserApi {
   ///
   /// 
   Future<String> loginUser(String username, String password) async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
     if(username == null) {
@@ -312,7 +312,7 @@ class UserApi {
   ///
   /// 
   Future logoutUser() async {
-    Object postBody = null;
+    Object postBody;
 
     // verify required params are set
 
diff --git a/samples/client/petstore/dart2/openapi/lib/api_client.dart b/samples/client/petstore/dart2/openapi/lib/api_client.dart
index 042deb946ae..f1e49792f90 100644
--- a/samples/client/petstore/dart2/openapi/lib/api_client.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api_client.dart
@@ -10,18 +10,18 @@ class QueryParam {
 class ApiClient {
 
   String basePath;
-  var client = new Client();
+  var client = Client();
 
   Map<String, String> _defaultHeaderMap = {};
   Map<String, Authentication> _authentications = {};
 
-  final _RegList = new RegExp(r'^List<(.*)>$');
-  final _RegMap = new RegExp(r'^Map<String,(.*)>$');
+  final _regList = RegExp(r'^List<(.*)>$');
+  final _regMap = RegExp(r'^Map<String,(.*)>$');
 
   ApiClient({this.basePath: "http://petstore.swagger.io/v2"}) {
     // Setup authentications (key: authentication name, value: authentication).
-    _authentications['api_key'] = new ApiKeyAuth("header", "api_key");
-    _authentications['petstore_auth'] = new OAuth();
+    _authentications['api_key'] = ApiKeyAuth("header", "api_key");
+    _authentications['petstore_auth'] = OAuth();
   }
 
   void addDefaultHeader(String key, String value) {
@@ -40,36 +40,36 @@ class ApiClient {
         case 'double':
           return value is double ? value : double.parse('$value');
         case 'ApiResponse':
-          return new ApiResponse.fromJson(value);
+          return ApiResponse.fromJson(value);
         case 'Category':
-          return new Category.fromJson(value);
+          return Category.fromJson(value);
         case 'Order':
-          return new Order.fromJson(value);
+          return Order.fromJson(value);
         case 'Pet':
-          return new Pet.fromJson(value);
+          return Pet.fromJson(value);
         case 'Tag':
-          return new Tag.fromJson(value);
+          return Tag.fromJson(value);
         case 'User':
-          return new User.fromJson(value);
+          return User.fromJson(value);
         default:
           {
             Match match;
             if (value is List &&
-                (match = _RegList.firstMatch(targetType)) != null) {
+                (match = _regList.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
               return value.map((v) => _deserialize(v, newTargetType)).toList();
             } else if (value is Map &&
-                (match = _RegMap.firstMatch(targetType)) != null) {
+                (match = _regMap.firstMatch(targetType)) != null) {
               var newTargetType = match[1];
-              return new Map.fromIterables(value.keys,
+              return Map.fromIterables(value.keys,
                   value.values.map((v) => _deserialize(v, newTargetType)));
             }
           }
       }
     } catch (e, stack) {
-      throw new ApiException.withInner(500, 'Exception during deserialization.', e, stack);
+      throw ApiException.withInner(500, 'Exception during deserialization.', e, stack);
     }
-    throw new ApiException(500, 'Could not find a suitable class for deserialization');
+    throw ApiException(500, 'Could not find a suitable class for deserialization');
   }
 
   dynamic deserialize(String json, String targetType) {
@@ -116,7 +116,7 @@ class ApiClient {
     headerParams['Content-Type'] = contentType;
 
     if(body is MultipartRequest) {
-      var request = new MultipartRequest(method, Uri.parse(url));
+      var request = MultipartRequest(method, Uri.parse(url));
       request.fields.addAll(body.fields);
       request.files.addAll(body.files);
       request.headers.addAll(body.headers);
@@ -145,7 +145,7 @@ class ApiClient {
   void _updateParamsForAuth(List<String> authNames, List<QueryParam> queryParams, Map<String, String> headerParams) {
     authNames.forEach((authName) {
       Authentication auth = _authentications[authName];
-      if (auth == null) throw new ArgumentError("Authentication undefined: " + authName);
+      if (auth == null) throw ArgumentError("Authentication undefined: " + authName);
       auth.applyToParams(queryParams, headerParams);
     });
   }
diff --git a/samples/client/petstore/dart2/openapi/lib/api_exception.dart b/samples/client/petstore/dart2/openapi/lib/api_exception.dart
index f188fd125a4..668abe2c96b 100644
--- a/samples/client/petstore/dart2/openapi/lib/api_exception.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api_exception.dart
@@ -2,9 +2,9 @@ part of openapi.api;
 
 class ApiException implements Exception {
   int code = 0;
-  String message = null;
-  Exception innerException = null;
-  StackTrace stackTrace = null;
+  String message;
+  Exception innerException;
+  StackTrace stackTrace;
 
   ApiException(this.code, this.message);
 
@@ -17,7 +17,7 @@ class ApiException implements Exception {
       return "ApiException $code: $message";
     }
 
-    return "ApiException $code: $message (Inner exception: ${innerException})\n\n" +
+    return "ApiException $code: $message (Inner exception: $innerException)\n\n" +
         stackTrace.toString();
   }
 }
diff --git a/samples/client/petstore/dart2/openapi/lib/api_helper.dart b/samples/client/petstore/dart2/openapi/lib/api_helper.dart
index 79af4521d5b..a516a68d264 100644
--- a/samples/client/petstore/dart2/openapi/lib/api_helper.dart
+++ b/samples/client/petstore/dart2/openapi/lib/api_helper.dart
@@ -11,7 +11,7 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
   if (name == null || name.isEmpty || value == null) return params;
 
   if (value is! List) {
-    params.add(new QueryParam(name, parameterToString(value)));
+    params.add(QueryParam(name, parameterToString(value)));
     return params;
   }
 
@@ -23,12 +23,12 @@ Iterable<QueryParam> _convertParametersForCollectionFormat(
                      : collectionFormat; // default: csv
 
   if (collectionFormat == "multi") {
-    return values.map((v) => new QueryParam(name, parameterToString(v)));
+    return values.map((v) => QueryParam(name, parameterToString(v)));
   }
 
   String delimiter = _delimiters[collectionFormat] ?? ",";
 
-  params.add(new QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
+  params.add(QueryParam(name, values.map((v) => parameterToString(v)).join(delimiter)));
   return params;
 }
 
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart b/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
index f9617f7ae4d..8caf6ab5eba 100644
--- a/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
+++ b/samples/client/petstore/dart2/openapi/lib/auth/api_key_auth.dart
@@ -19,7 +19,7 @@ class ApiKeyAuth implements Authentication {
     }
 
     if (location == 'query' && value != null) {
-      queryParams.add(new QueryParam(paramName, value));
+      queryParams.add(QueryParam(paramName, value));
     } else if (location == 'header' && value != null) {
       headerParams[paramName] = value;
     }
diff --git a/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart b/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
index 13bfd799743..aa08e5cdb4d 100644
--- a/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
+++ b/samples/client/petstore/dart2/openapi/lib/auth/oauth.dart
@@ -3,8 +3,7 @@ part of openapi.api;
 class OAuth implements Authentication {
   String accessToken;
 
-  OAuth({this.accessToken}) {
-  }
+  OAuth({this.accessToken});
 
   @override
   void applyToParams(List<QueryParam> queryParams, Map<String, String> headerParams) {
diff --git a/samples/client/petstore/dart2/openapi/lib/model/pet.dart b/samples/client/petstore/dart2/openapi/lib/model/pet.dart
index 4d2f77a1a5a..da9de49b678 100644
--- a/samples/client/petstore/dart2/openapi/lib/model/pet.dart
+++ b/samples/client/petstore/dart2/openapi/lib/model/pet.dart
@@ -26,7 +26,7 @@ class Pet {
     id = json['id'];
     category = new Category.fromJson(json['category']);
     name = json['name'];
-    photoUrls = (json['photoUrls'] as List).map((item) => item as String).toList();
+    photoUrls = ((json['photoUrls'] ?? []) as List).map((item) => item as String).toList();
     tags = Tag.listFromJson(json['tags']);
     status = json['status'];
   }
diff --git a/samples/client/petstore/dart2/openapi/pubspec.yaml b/samples/client/petstore/dart2/openapi/pubspec.yaml
index 9ccf0e524ad..d54efb46a2e 100644
--- a/samples/client/petstore/dart2/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi/pubspec.yaml
@@ -1,7 +1,5 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
-environment:
-  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
-- 
GitLab


From 5feff6b0c9b60ee90ae91decea1913f86e9eb12d Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 17:46:32 +0800
Subject: [PATCH 13/16] Update pom.xml

---
 samples/client/petstore/dart2/petstore/pom.xml | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/samples/client/petstore/dart2/petstore/pom.xml b/samples/client/petstore/dart2/petstore/pom.xml
index 787349feb66..bec050a7944 100644
--- a/samples/client/petstore/dart2/petstore/pom.xml
+++ b/samples/client/petstore/dart2/petstore/pom.xml
@@ -48,7 +48,8 @@
                         <configuration>
                             <executable>pub</executable>
                             <arguments>
-                                <argument>build</argument>
+                                <argument>run</argument>
+                                <argument>build_runner</argument>
                                 <argument>test</argument>
                             </arguments>
                         </configuration>
-- 
GitLab


From 10309967f4519ed86919b7d6a03ef14ed50bec6e Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 18:10:49 +0800
Subject: [PATCH 14/16] Added SDK version constraints in pubspec.mustache

---
 .../openapi-generator/src/main/resources/dart2/pubspec.mustache | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache b/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache
index a338854b748..388572afe62 100644
--- a/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache
+++ b/modules/openapi-generator/src/main/resources/dart2/pubspec.mustache
@@ -1,5 +1,7 @@
 name: {{pubName}}
 version: {{pubVersion}}
 description: {{pubDescription}}
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
-- 
GitLab


From 70bbee6fc63f3462b3546bf64ee88d48bde3f735 Mon Sep 17 00:00:00 2001
From: Yimin Lin <ylin@swipesight.com>
Date: Tue, 28 Aug 2018 18:14:27 +0800
Subject: [PATCH 15/16] Run bin/dart2-petstore.sh to regenerate libraries

---
 .../client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml | 2 ++
 .../client/petstore/dart2/openapi-browser-client/pubspec.yaml   | 2 ++
 samples/client/petstore/dart2/openapi/pubspec.yaml              | 2 ++
 3 files changed, 6 insertions(+)

diff --git a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/flutter_petstore/openapi/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi-browser-client/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
diff --git a/samples/client/petstore/dart2/openapi/pubspec.yaml b/samples/client/petstore/dart2/openapi/pubspec.yaml
index d54efb46a2e..9ccf0e524ad 100644
--- a/samples/client/petstore/dart2/openapi/pubspec.yaml
+++ b/samples/client/petstore/dart2/openapi/pubspec.yaml
@@ -1,5 +1,7 @@
 name: openapi
 version: 1.0.0
 description: OpenAPI API client
+environment:
+  sdk: '>=2.0.0 <3.0.0'
 dependencies:
   http: '>=0.11.1 <0.12.0'
-- 
GitLab


From 7d2edf4713c5c3bfb2d1698c4fd110e5b2a07bd9 Mon Sep 17 00:00:00 2001
From: William Cheng <wing328hk@gmail.com>
Date: Sat, 1 Sep 2018 01:07:47 +0800
Subject: [PATCH 16/16] move dart2 test to the end

---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 626fe5cec71..097ac931521 100644
--- a/pom.xml
+++ b/pom.xml
@@ -978,7 +978,6 @@
             </activation>
             <modules>
                 <!-- clients -->
-                <module>samples/client/petstore/dart2/petstore</module>
                 <module>samples/client/petstore/haskell-http-client</module>
                 <module>samples/client/petstore/elm</module>
                 <module>samples/client/petstore/groovy</module>
@@ -1010,6 +1009,7 @@
                 <!--<module>samples/client/petstore/bash</module>-->
                 <module>samples/client/petstore/ruby</module>
                 <module>samples/server/petstore/rust-server</module>
+                <module>samples/client/petstore/dart2/petstore</module>
             </modules>
         </profile>
         <profile>
-- 
GitLab