public PhpClientCodegen() {
    super();

    // clear import mapping (from default generator) as php does not use it
    // at the moment
    importMapping.clear();

    supportsInheritance = true;
    outputFolder = "generated-code" + File.separator + "php";
    modelTemplateFiles.put("model.mustache", ".php");
    apiTemplateFiles.put("api.mustache", ".php");
    modelTestTemplateFiles.put("model_test.mustache", ".php");
    apiTestTemplateFiles.put("api_test.mustache", ".php");
    embeddedTemplateDir = templateDir = "php";
    apiPackage = invokerPackage + "\\" + apiDirName;
    modelPackage = invokerPackage + "\\" + modelDirName;

    modelDocTemplateFiles.put("model_doc.mustache", ".md");
    apiDocTemplateFiles.put("api_doc.mustache", ".md");

    setReservedWordsLowerCase(
        Arrays.asList(
            // local variables used in api methods (endpoints)
            "resourcePath",
            "httpBody",
            "queryParams",
            "headerParams",
            "formParams",
            "_header_accept",
            "_tempBody",

            // PHP reserved words
            "__halt_compiler",
            "abstract",
            "and",
            "array",
            "as",
            "break",
            "callable",
            "case",
            "catch",
            "class",
            "clone",
            "const",
            "continue",
            "declare",
            "default",
            "die",
            "do",
            "echo",
            "else",
            "elseif",
            "empty",
            "enddeclare",
            "endfor",
            "endforeach",
            "endif",
            "endswitch",
            "endwhile",
            "eval",
            "exit",
            "extends",
            "final",
            "for",
            "foreach",
            "function",
            "global",
            "goto",
            "if",
            "implements",
            "include",
            "include_once",
            "instanceof",
            "insteadof",
            "interface",
            "isset",
            "list",
            "namespace",
            "new",
            "or",
            "print",
            "private",
            "protected",
            "public",
            "require",
            "require_once",
            "return",
            "static",
            "switch",
            "throw",
            "trait",
            "try",
            "unset",
            "use",
            "var",
            "while",
            "xor"));

    // ref: http://php.net/manual/en/language.types.intro.php
    languageSpecificPrimitives =
        new HashSet<String>(
            Arrays.asList(
                "bool",
                "boolean",
                "int",
                "integer",
                "double",
                "float",
                "string",
                "object",
                "DateTime",
                "mixed",
                "number",
                "void",
                "byte"));

    instantiationTypes.put("array", "array");
    instantiationTypes.put("map", "map");

    // provide primitives to mustache template
    List sortedLanguageSpecificPrimitives = new ArrayList(languageSpecificPrimitives);
    Collections.sort(sortedLanguageSpecificPrimitives);
    String primitives = "'" + StringUtils.join(sortedLanguageSpecificPrimitives, "', '") + "'";
    additionalProperties.put("primitives", primitives);

    // ref: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md#data-types
    typeMapping = new HashMap<String, String>();
    typeMapping.put("integer", "int");
    typeMapping.put("long", "int");
    typeMapping.put("number", "float");
    typeMapping.put("float", "float");
    typeMapping.put("double", "double");
    typeMapping.put("string", "string");
    typeMapping.put("byte", "int");
    typeMapping.put("boolean", "bool");
    typeMapping.put("Date", "\\DateTime");
    typeMapping.put("DateTime", "\\DateTime");
    typeMapping.put("file", "\\SplFileObject");
    typeMapping.put("map", "map");
    typeMapping.put("array", "array");
    typeMapping.put("list", "array");
    typeMapping.put("object", "object");
    typeMapping.put("binary", "string");
    typeMapping.put("ByteArray", "string");
    typeMapping.put("UUID", "string");

    cliOptions.add(
        new CliOption(CodegenConstants.MODEL_PACKAGE, CodegenConstants.MODEL_PACKAGE_DESC));
    cliOptions.add(new CliOption(CodegenConstants.API_PACKAGE, CodegenConstants.API_PACKAGE_DESC));
    cliOptions.add(
        new CliOption(
                VARIABLE_NAMING_CONVENTION, "naming convention of variable name, e.g. camelCase.")
            .defaultValue("snake_case"));
    cliOptions.add(
        new CliOption(
            CodegenConstants.INVOKER_PACKAGE,
            "The main namespace to use for all classes. e.g. Yay\\Pets"));
    cliOptions.add(
        new CliOption(PACKAGE_PATH, "The main package name for classes. e.g. GeneratedPetstore"));
    cliOptions.add(
        new CliOption(SRC_BASE_PATH, "The directory under packagePath to serve as source root."));
    cliOptions.add(
        new CliOption(
            COMPOSER_VENDOR_NAME,
            "The vendor name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. yaypets. IMPORTANT NOTE (2016/03): composerVendorName will be deprecated and replaced by gitUserId in the next swagger-codegen release"));
    cliOptions.add(new CliOption(CodegenConstants.GIT_USER_ID, CodegenConstants.GIT_USER_ID_DESC));
    cliOptions.add(
        new CliOption(
            COMPOSER_PROJECT_NAME,
            "The project name used in the composer package name. The template uses {{composerVendorName}}/{{composerProjectName}} for the composer package name. e.g. petstore-client. IMPORTANT NOTE (2016/03): composerProjectName will be deprecated and replaced by gitRepoId in the next swagger-codegen release"));
    cliOptions.add(new CliOption(CodegenConstants.GIT_REPO_ID, CodegenConstants.GIT_REPO_ID_DESC));
    cliOptions.add(
        new CliOption(
            CodegenConstants.ARTIFACT_VERSION,
            "The version to use in the composer package version field. e.g. 1.2.3"));
    cliOptions.add(
        new CliOption(
                CodegenConstants.HIDE_GENERATION_TIMESTAMP,
                "hides the timestamp when files were generated")
            .defaultValue(Boolean.TRUE.toString()));
  }
  public PythonClientCodegen() {
    super();

    modelPackage = "models";
    apiPackage = "api";
    outputFolder = "generated-code" + File.separatorChar + "python";

    modelTemplateFiles.put("model.mustache", ".py");
    apiTemplateFiles.put("api.mustache", ".py");

    modelTestTemplateFiles.put("model_test.mustache", ".py");
    apiTestTemplateFiles.put("api_test.mustache", ".py");

    embeddedTemplateDir = templateDir = "python";

    modelDocTemplateFiles.put("model_doc.mustache", ".md");
    apiDocTemplateFiles.put("api_doc.mustache", ".md");

    testFolder = "test";

    languageSpecificPrimitives.clear();
    languageSpecificPrimitives.add("int");
    languageSpecificPrimitives.add("float");
    languageSpecificPrimitives.add("list");
    languageSpecificPrimitives.add("bool");
    languageSpecificPrimitives.add("str");
    languageSpecificPrimitives.add("datetime");
    languageSpecificPrimitives.add("date");
    languageSpecificPrimitives.add("object");

    typeMapping.clear();
    typeMapping.put("integer", "int");
    typeMapping.put("float", "float");
    typeMapping.put("number", "float");
    typeMapping.put("long", "int");
    typeMapping.put("double", "float");
    typeMapping.put("array", "list");
    typeMapping.put("map", "dict");
    typeMapping.put("boolean", "bool");
    typeMapping.put("string", "str");
    typeMapping.put("date", "date");
    typeMapping.put("DateTime", "datetime");
    typeMapping.put("object", "object");
    typeMapping.put("file", "file");
    // TODO binary should be mapped to byte array
    // mapped to String as a workaround
    typeMapping.put("binary", "str");
    typeMapping.put("ByteArray", "str");
    // map uuid to string for the time being
    typeMapping.put("UUID", "str");

    // from https://docs.python.org/release/2.5.4/ref/keywords.html
    setReservedWordsLowerCase(
        Arrays.asList(
            // local variable name used in API methods (endpoints)
            "all_params",
            "resource_path",
            "path_params",
            "query_params",
            "header_params",
            "form_params",
            "local_var_files",
            "body_params",
            "auth_settings",
            // @property
            "property",
            // python reserved words
            "and",
            "del",
            "from",
            "not",
            "while",
            "as",
            "elif",
            "global",
            "or",
            "with",
            "assert",
            "else",
            "if",
            "pass",
            "yield",
            "break",
            "except",
            "import",
            "print",
            "class",
            "exec",
            "in",
            "raise",
            "continue",
            "finally",
            "is",
            "return",
            "def",
            "for",
            "lambda",
            "try",
            "self"));

    regexModifiers = new HashMap<Character, String>();
    regexModifiers.put('i', "IGNORECASE");
    regexModifiers.put('l', "LOCALE");
    regexModifiers.put('m', "MULTILINE");
    regexModifiers.put('s', "DOTALL");
    regexModifiers.put('u', "UNICODE");
    regexModifiers.put('x', "VERBOSE");

    cliOptions.clear();
    cliOptions.add(
        new CliOption(
                CodegenConstants.PACKAGE_NAME, "python package name (convention: snake_case).")
            .defaultValue("swagger_client"));
    cliOptions.add(
        new CliOption(CodegenConstants.PACKAGE_VERSION, "python package version.")
            .defaultValue("1.0.0"));
    cliOptions.add(
        CliOption.newBoolean(
                CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG,
                CodegenConstants.SORT_PARAMS_BY_REQUIRED_FLAG_DESC)
            .defaultValue(Boolean.TRUE.toString()));
  }
  @Override
  public void processOpts() {
    super.processOpts();

    // default HIDE_GENERATION_TIMESTAMP to true
    if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
      additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
    } else {
      additionalProperties.put(
          CodegenConstants.HIDE_GENERATION_TIMESTAMP,
          Boolean.valueOf(
              additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
    }

    if (additionalProperties.containsKey(PACKAGE_PATH)) {
      this.setPackagePath((String) additionalProperties.get(PACKAGE_PATH));
    } else {
      additionalProperties.put(PACKAGE_PATH, packagePath);
    }

    if (additionalProperties.containsKey(SRC_BASE_PATH)) {
      this.setSrcBasePath((String) additionalProperties.get(SRC_BASE_PATH));
    } else {
      additionalProperties.put(SRC_BASE_PATH, srcBasePath);
    }

    if (additionalProperties.containsKey(CodegenConstants.INVOKER_PACKAGE)) {
      this.setInvokerPackage((String) additionalProperties.get(CodegenConstants.INVOKER_PACKAGE));
    } else {
      additionalProperties.put(CodegenConstants.INVOKER_PACKAGE, invokerPackage);
    }

    if (!additionalProperties.containsKey(CodegenConstants.MODEL_PACKAGE)) {
      additionalProperties.put(CodegenConstants.MODEL_PACKAGE, modelPackage);
    }

    if (!additionalProperties.containsKey(CodegenConstants.API_PACKAGE)) {
      additionalProperties.put(CodegenConstants.API_PACKAGE, apiPackage);
    }

    if (additionalProperties.containsKey(COMPOSER_PROJECT_NAME)) {
      this.setComposerProjectName((String) additionalProperties.get(COMPOSER_PROJECT_NAME));
    } else {
      additionalProperties.put(COMPOSER_PROJECT_NAME, composerProjectName);
    }

    if (additionalProperties.containsKey(CodegenConstants.GIT_USER_ID)) {
      this.setGitUserId((String) additionalProperties.get(CodegenConstants.GIT_USER_ID));
    } else {
      additionalProperties.put(CodegenConstants.GIT_USER_ID, gitUserId);
    }

    if (additionalProperties.containsKey(COMPOSER_VENDOR_NAME)) {
      this.setComposerVendorName((String) additionalProperties.get(COMPOSER_VENDOR_NAME));
    } else {
      additionalProperties.put(COMPOSER_VENDOR_NAME, composerVendorName);
    }

    if (additionalProperties.containsKey(CodegenConstants.GIT_REPO_ID)) {
      this.setGitRepoId((String) additionalProperties.get(CodegenConstants.GIT_REPO_ID));
    } else {
      additionalProperties.put(CodegenConstants.GIT_REPO_ID, gitRepoId);
    }

    if (additionalProperties.containsKey(CodegenConstants.ARTIFACT_VERSION)) {
      this.setArtifactVersion((String) additionalProperties.get(CodegenConstants.ARTIFACT_VERSION));
    } else {
      additionalProperties.put(CodegenConstants.ARTIFACT_VERSION, artifactVersion);
    }

    if (additionalProperties.containsKey(VARIABLE_NAMING_CONVENTION)) {
      this.setParameterNamingConvention(
          (String) additionalProperties.get(VARIABLE_NAMING_CONVENTION));
    }

    additionalProperties.put("escapedInvokerPackage", invokerPackage.replace("\\", "\\\\"));

    // make api and model doc path available in mustache template
    additionalProperties.put("apiDocPath", apiDocPath);
    additionalProperties.put("modelDocPath", modelDocPath);

    // make test path available in mustache template
    additionalProperties.put("testBasePath", testBasePath);

    supportingFiles.add(
        new SupportingFile(
            "configuration.mustache",
            toPackagePath(invokerPackage, srcBasePath),
            "Configuration.php"));
    supportingFiles.add(
        new SupportingFile(
            "ApiClient.mustache", toPackagePath(invokerPackage, srcBasePath), "ApiClient.php"));
    supportingFiles.add(
        new SupportingFile(
            "ApiException.mustache",
            toPackagePath(invokerPackage, srcBasePath),
            "ApiException.php"));
    supportingFiles.add(
        new SupportingFile(
            "ObjectSerializer.mustache",
            toPackagePath(invokerPackage, srcBasePath),
            "ObjectSerializer.php"));
    supportingFiles.add(new SupportingFile("composer.mustache", getPackagePath(), "composer.json"));
    supportingFiles.add(new SupportingFile("autoload.mustache", getPackagePath(), "autoload.php"));
    supportingFiles.add(new SupportingFile("README.mustache", getPackagePath(), "README.md"));
    supportingFiles.add(new SupportingFile(".travis.yml", getPackagePath(), ".travis.yml"));
    supportingFiles.add(
        new SupportingFile("git_push.sh.mustache", getPackagePath(), "git_push.sh"));
    // apache v2 license
    supportingFiles.add(new SupportingFile("LICENSE", getPackagePath(), "LICENSE"));
  }