diff --git a/modules/openapi-generator-gradle-plugin/bin/main/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt b/modules/openapi-generator-gradle-plugin/bin/main/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
index 7c6ecd099da6706c2dcd5a579508599b0b743657..1982dd3dc2562b942227cd2d941909a9faeee876 100644
--- a/modules/openapi-generator-gradle-plugin/bin/main/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
+++ b/modules/openapi-generator-gradle-plugin/bin/main/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
@@ -28,6 +28,7 @@ import org.gradle.kotlin.dsl.property
 import org.openapitools.codegen.CodegenConstants
 import org.openapitools.codegen.DefaultGenerator
 import org.openapitools.codegen.config.CodegenConfigurator
+import org.openapitools.codegen.config.GeneratorProperties
 
 
 /**
@@ -352,36 +353,36 @@ open class GenerateTask : DefaultTask() {
         try {
             if (systemProperties.isPresent) {
                 systemProperties.get().forEach { (key, value) ->
-                    // System.setProperty returns the original value for a key, or null.
+                    // GeneratorProperties.setProperty returns the original value for a key, or null.
                     // Cache the original value or null…we will late put the properties back in their original state.
-                    originalEnvironmentVariables[key] = System.setProperty(key, value)
+                    originalEnvironmentVariables[key] = GeneratorProperties.setProperty(key, value)
                     configurator.addSystemProperty(key, value)
                 }
             }
 
             if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.SUPPORTING_FILES)
+                GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES)
             }
 
             if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.MODELS)
+                GeneratorProperties.clearProperty(CodegenConstants.MODELS)
             }
 
             if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.APIS)
+                GeneratorProperties.clearProperty(CodegenConstants.APIS)
             }
 
-            System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
-            System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
-            System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
-            System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
-            System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
 
             // now override with any specified parameters
             verbose.ifNotEmpty { value ->
@@ -542,13 +543,7 @@ open class GenerateTask : DefaultTask() {
             }
         } finally {
             // Reset all modified system properties back to their original state
-            originalEnvironmentVariables.forEach {
-                when {
-                    it.value == null -> System.clearProperty(it.key)
-                    else -> System.setProperty(it.key, it.value)
-                }
-            }
-            originalEnvironmentVariables.clear()
+            GeneratorProperties.reset()
         }
     }
 }
diff --git a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
index 7c6ecd099da6706c2dcd5a579508599b0b743657..e5cffdbe6a0b41e7f497e8521332f9e3ca28097c 100644
--- a/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
+++ b/modules/openapi-generator-gradle-plugin/src/main/kotlin/org/openapitools/generator/gradle/plugin/tasks/GenerateTask.kt
@@ -28,6 +28,7 @@ import org.gradle.kotlin.dsl.property
 import org.openapitools.codegen.CodegenConstants
 import org.openapitools.codegen.DefaultGenerator
 import org.openapitools.codegen.config.CodegenConfigurator
+import org.openapitools.codegen.config.GeneratorProperties
 
 
 /**
@@ -323,8 +324,6 @@ open class GenerateTask : DefaultTask() {
     @get:Internal
     val configOptions = project.objects.property<Map<String, String>>()
 
-    private val originalEnvironmentVariables = mutableMapOf<String, String?>()
-
     private fun <T : Any?> Property<T>.ifNotEmpty(block: Property<T>.(T) -> Unit) {
         if (isPresent) {
             val item: T? = get()
@@ -352,36 +351,33 @@ open class GenerateTask : DefaultTask() {
         try {
             if (systemProperties.isPresent) {
                 systemProperties.get().forEach { (key, value) ->
-                    // System.setProperty returns the original value for a key, or null.
-                    // Cache the original value or null…we will late put the properties back in their original state.
-                    originalEnvironmentVariables[key] = System.setProperty(key, value)
                     configurator.addSystemProperty(key, value)
                 }
             }
 
             if (supportingFilesConstrainedTo.isPresent && supportingFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.SUPPORTING_FILES)
+                GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES)
             }
 
             if (modelFilesConstrainedTo.isPresent && modelFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.MODELS, modelFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.MODELS)
+                GeneratorProperties.clearProperty(CodegenConstants.MODELS)
             }
 
             if (apiFilesConstrainedTo.isPresent && apiFilesConstrainedTo.get().isNotEmpty()) {
-                System.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
+                GeneratorProperties.setProperty(CodegenConstants.APIS, apiFilesConstrainedTo.get().joinToString(","))
             } else {
-                System.clearProperty(CodegenConstants.APIS)
+                GeneratorProperties.clearProperty(CodegenConstants.APIS)
             }
 
-            System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
-            System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
-            System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
-            System.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
-            System.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.get().toString())
+            GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.get().toString())
 
             // now override with any specified parameters
             verbose.ifNotEmpty { value ->
@@ -541,14 +537,7 @@ open class GenerateTask : DefaultTask() {
                 throw GradleException("Code generation failed.", e)
             }
         } finally {
-            // Reset all modified system properties back to their original state
-            originalEnvironmentVariables.forEach {
-                when {
-                    it.value == null -> System.clearProperty(it.key)
-                    else -> System.setProperty(it.key, it.value)
-                }
-            }
-            originalEnvironmentVariables.clear()
+            GeneratorProperties.reset()
         }
     }
 }
diff --git a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java
index ce04ac293492312378746216f546238b7aa2dbdc..695f6167397dcf74e420c2535960d5dee96a0870 100644
--- a/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java
+++ b/modules/openapi-generator-maven-plugin/src/main/java/org/openapitools/codegen/plugin/CodeGenMojo.java
@@ -51,6 +51,7 @@ import org.openapitools.codegen.CodegenConfig;
 import org.openapitools.codegen.CodegenConstants;
 import org.openapitools.codegen.DefaultGenerator;
 import org.openapitools.codegen.config.CodegenConfigurator;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.sonatype.plexus.build.incremental.BuildContext;
 import org.sonatype.plexus.build.incremental.DefaultBuildContext;
 import org.slf4j.Logger;
@@ -499,28 +500,28 @@ public class CodeGenMojo extends AbstractMojo {
 
             // Set generation options
             if (null != generateApis && generateApis) {
-                System.setProperty(CodegenConstants.APIS, "");
+                GeneratorProperties.setProperty(CodegenConstants.APIS, "");
             } else {
-                System.clearProperty(CodegenConstants.APIS);
+                GeneratorProperties.clearProperty(CodegenConstants.APIS);
             }
 
             if (null != generateModels && generateModels) {
-                System.setProperty(CodegenConstants.MODELS, modelsToGenerate);
+                GeneratorProperties.setProperty(CodegenConstants.MODELS, modelsToGenerate);
             } else {
-                System.clearProperty(CodegenConstants.MODELS);
+                GeneratorProperties.clearProperty(CodegenConstants.MODELS);
             }
 
             if (null != generateSupportingFiles && generateSupportingFiles) {
-                System.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
+                GeneratorProperties.setProperty(CodegenConstants.SUPPORTING_FILES, supportingFilesToGenerate);
             } else {
-                System.clearProperty(CodegenConstants.SUPPORTING_FILES);
+                GeneratorProperties.clearProperty(CodegenConstants.SUPPORTING_FILES);
             }
 
-            System.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
-            System.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
-            System.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
-            System.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
-            System.setProperty(CodegenConstants.WITH_XML, withXml.toString());
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_TESTS, generateModelTests.toString());
+            GeneratorProperties.setProperty(CodegenConstants.MODEL_DOCS, generateModelDocumentation.toString());
+            GeneratorProperties.setProperty(CodegenConstants.API_TESTS, generateApiTests.toString());
+            GeneratorProperties.setProperty(CodegenConstants.API_DOCS, generateApiDocumentation.toString());
+            GeneratorProperties.setProperty(CodegenConstants.WITH_XML, withXml.toString());
 
             if (configOptions != null) {
                 // Retained for backwards-compataibility with configOptions -> instantiation-types
@@ -593,13 +594,13 @@ public class CodeGenMojo extends AbstractMojo {
             if (environmentVariables != null) {
 
                 for (String key : environmentVariables.keySet()) {
-                    originalEnvironmentVariables.put(key, System.getProperty(key));
+                    originalEnvironmentVariables.put(key, GeneratorProperties.getProperty(key));
                     String value = environmentVariables.get(key);
                     if (value == null) {
                         // don't put null values
                         value = "";
                     }
-                    System.setProperty(key, value);
+                    GeneratorProperties.setProperty(key, value);
                     configurator.addSystemProperty(key, value);
                 }
             }
@@ -680,9 +681,9 @@ public class CodeGenMojo extends AbstractMojo {
         // when running the plugin multiple consecutive times with different configurations.
         for (Map.Entry<String, String> entry : originalEnvironmentVariables.entrySet()) {
             if (entry.getValue() == null) {
-                System.clearProperty(entry.getKey());
+                GeneratorProperties.clearProperty(entry.getKey());
             } else {
-                System.setProperty(entry.getKey(), entry.getValue());
+                GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
             }
         }
     }
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
index 2462a1418f6d3653ddca5f1ef9cfe7693851c70c..3ed5ecb96e6d8ebe37c30eb8d8b7d3523c7521a4 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java
@@ -53,6 +53,7 @@ import org.apache.commons.lang3.StringEscapeUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.tuple.Pair;
 import org.openapitools.codegen.CodegenDiscriminator.MappedModel;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.openapitools.codegen.examples.ExampleGenerator;
 import org.openapitools.codegen.serializer.SerializerUtils;
 import org.openapitools.codegen.utils.ModelUtils;
@@ -2792,7 +2793,7 @@ public class DefaultCodegen implements CodegenConfig {
         }
         codegenParameter.jsonSchema = Json.pretty(parameter);
 
-        if (System.getProperty("debugParser") != null) {
+        if (GeneratorProperties.getProperty("debugParser") != null) {
             LOGGER.info("working on Parameter " + parameter.getName());
             LOGGER.info("JSON schema: " + codegenParameter.jsonSchema);
         }
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
index 1ffa43cc1451fdd5c16e83b6fb05e8fad7e3a2fb..74ff0088666ff7ad622be9ae447c7fb7bb163d24 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultGenerator.java
@@ -37,6 +37,7 @@ import io.swagger.v3.oas.models.tags.Tag;
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.lang3.ObjectUtils;
 import org.apache.commons.lang3.StringUtils;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.openapitools.codegen.ignore.CodegenIgnoreProcessor;
 import org.openapitools.codegen.utils.ImplementationVersion;
 import org.openapitools.codegen.utils.ModelUtils;
@@ -129,9 +130,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
     private void configureGeneratorProperties() {
         // allows generating only models by specifying a CSV of models to generate, or empty for all
         // NOTE: Boolean.TRUE is required below rather than `true` because of JVM boxing constraints and type inference.
-        generateApis = System.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
-        generateModels = System.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
-        generateSupportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
+        generateApis = GeneratorProperties.getProperty(CodegenConstants.APIS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.APIS, null);
+        generateModels = GeneratorProperties.getProperty(CodegenConstants.MODELS) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODELS, null);
+        generateSupportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES) != null ? Boolean.TRUE : getGeneratorPropertyDefaultSwitch(CodegenConstants.SUPPORTING_FILES, null);
 
         if (generateApis == null && generateModels == null && generateSupportingFiles == null) {
             // no specifics are set, generate everything
@@ -149,10 +150,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
         }
         // model/api tests and documentation options rely on parent generate options (api or model) and no other options.
         // They default to true in all scenarios and can only be marked false explicitly
-        generateModelTests = System.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
-        generateModelDocumentation = System.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
-        generateApiTests = System.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
-        generateApiDocumentation = System.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(System.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
+        generateModelTests = GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_TESTS, true);
+        generateModelDocumentation = GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.MODEL_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.MODEL_DOCS, true);
+        generateApiTests = GeneratorProperties.getProperty(CodegenConstants.API_TESTS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_TESTS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_TESTS, true);
+        generateApiDocumentation = GeneratorProperties.getProperty(CodegenConstants.API_DOCS) != null ? Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.API_DOCS)) : getGeneratorPropertyDefaultSwitch(CodegenConstants.API_DOCS, true);
 
 
         // Additional properties added for tests to exclude references in project related files
@@ -169,9 +170,9 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
             config.additionalProperties().put(CodegenConstants.EXCLUDE_TESTS, true);
         }
 
-        if (System.getProperty("debugOpenAPI") != null) {
+        if (GeneratorProperties.getProperty("debugOpenAPI") != null) {
             Json.prettyPrint(openAPI);
-        } else if (System.getProperty("debugSwagger") != null) {
+        } else if (GeneratorProperties.getProperty("debugSwagger") != null) {
             // This exists for backward compatibility
             // We fall to this block only if debugOpenAPI is null. No need to dump this twice.
             LOGGER.info("Please use system property 'debugOpenAPI' instead of 'debugSwagger'.");
@@ -330,7 +331,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
             return;
         }
 
-        String modelNames = System.getProperty("models");
+        String modelNames = GeneratorProperties.getProperty("models");
         Set<String> modelsToGenerate = null;
         if (modelNames != null && !modelNames.isEmpty()) {
             modelsToGenerate = new HashSet<String>(Arrays.asList(modelNames.split(",")));
@@ -403,8 +404,8 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
             } */
         });
 
-        Boolean skipFormModel = System.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
-                Boolean.valueOf(System.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
+        Boolean skipFormModel = GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL) != null ?
+                Boolean.valueOf(GeneratorProperties.getProperty(CodegenConstants.SKIP_FORM_MODEL)) :
                 getGeneratorPropertyDefaultSwitch(CodegenConstants.SKIP_FORM_MODEL, false);
 
         // process models only
@@ -497,7 +498,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
                 throw new RuntimeException("Could not generate model '" + modelName + "'", e);
             }
         }
-        if (System.getProperty("debugModels") != null) {
+        if (GeneratorProperties.getProperty("debugModels") != null) {
             LOGGER.info("############ Model info ############");
             Json.prettyPrint(allModels);
         }
@@ -510,7 +511,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
         }
         Map<String, List<CodegenOperation>> paths = processPaths(this.openAPI.getPaths());
         Set<String> apisToGenerate = null;
-        String apiNames = System.getProperty("apis");
+        String apiNames = GeneratorProperties.getProperty("apis");
         if (apiNames != null && !apiNames.isEmpty()) {
             apisToGenerate = new HashSet<String>(Arrays.asList(apiNames.split(",")));
         }
@@ -651,7 +652,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
                 throw new RuntimeException("Could not generate api file for '" + tag + "'", e);
             }
         }
-        if (System.getProperty("debugOperations") != null) {
+        if (GeneratorProperties.getProperty("debugOperations") != null) {
             LOGGER.info("############ Operation info ############");
             Json.prettyPrint(allOperations);
         }
@@ -663,7 +664,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
             return;
         }
         Set<String> supportingFilesToGenerate = null;
-        String supportingFiles = System.getProperty(CodegenConstants.SUPPORTING_FILES);
+        String supportingFiles = GeneratorProperties.getProperty(CodegenConstants.SUPPORTING_FILES);
         if (supportingFiles != null && !supportingFiles.isEmpty()) {
             supportingFilesToGenerate = new HashSet<String>(Arrays.asList(supportingFiles.split(",")));
         }
@@ -856,7 +857,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
 
         config.postProcessSupportingFileData(bundle);
 
-        if (System.getProperty("debugSupportingFiles") != null) {
+        if (GeneratorProperties.getProperty("debugSupportingFiles") != null) {
             LOGGER.info("############ Supporting file info ############");
             Json.prettyPrint(bundle);
         }
@@ -894,6 +895,10 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
         Map<String, Object> bundle = buildSupportFileBundle(allOperations, allModels);
         generateSupportingFiles(files, bundle);
         config.processOpenAPI(openAPI);
+        
+        // reset GeneratorProperties, so that the running thread can be reused for another generator-run
+        GeneratorProperties.reset();
+
         return files;
     }
 
@@ -943,7 +948,7 @@ public class DefaultGenerator extends AbstractGenerator implements Generator {
             return;
         }
 
-        if (System.getProperty("debugOperations") != null) {
+        if (GeneratorProperties.getProperty("debugOperations") != null) {
             LOGGER.info("processOperation: resourcePath= " + resourcePath + "\t;" + httpMethod + " " + operation + "\n");
         }
 
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java
index 6a991b9c9591cd8e38a30b837ba5410291f010da..071f7adb87ea0d3b8bde2a2c8eebd2a5bc91a963 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/CodegenConfigurator.java
@@ -629,15 +629,15 @@ public class CodegenConfigurator implements Serializable {
                 "\n - [debugOperations] prints operations passed to the template engine" +
                 "\n - [debugSupportingFiles] prints additional data passed to the template engine");
 
-        System.setProperty("debugOpenAPI", "");
-        System.setProperty("debugModels", "");
-        System.setProperty("debugOperations", "");
-        System.setProperty("debugSupportingFiles", "");
+        GeneratorProperties.setProperty("debugOpenAPI", "");
+        GeneratorProperties.setProperty("debugModels", "");
+        GeneratorProperties.setProperty("debugOperations", "");
+        GeneratorProperties.setProperty("debugSupportingFiles", "");
     }
 
     private void setSystemProperties() {
         for (Map.Entry<String, String> entry : systemProperties.entrySet()) {
-            System.setProperty(entry.getKey(), entry.getValue());
+            GeneratorProperties.setProperty(entry.getKey(), entry.getValue());
         }
     }
 
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/GeneratorProperties.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/GeneratorProperties.java
new file mode 100644
index 0000000000000000000000000000000000000000..97fcb07f2a5ac1cb83845aaae313e74d7a265f8c
--- /dev/null
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/config/GeneratorProperties.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2018 OpenAPI-Generator Contributors (https://openapi-generator.tech)
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openapitools.codegen.config;
+
+import java.util.Properties;
+
+/**
+ * GeneratorProperties encapsulates SystemProperties, since the codegen mechanism heavily relies on a stable,
+ * non-changing System Property Basis. Using plain System.(get|set|clear)Property raises Race-Conditions in combination
+ * with Code, that uses System.setProperties (e.g. maven-surefire-plugin).
+ * 
+ * @author gndrm
+ * @since 2018
+ */
+public class GeneratorProperties {
+
+    private static ThreadLocal<Properties> properties = new InheritableThreadLocal<Properties>() {
+        @Override
+        protected Properties initialValue() {
+            return (Properties) System.getProperties().clone();
+        };
+    };
+
+    public static String getProperty(String key, String defaultValue) {
+        return properties.get().getProperty(key, defaultValue);
+    }
+
+    public static String getProperty(String key) {
+        return properties.get().getProperty(key);
+    }
+
+    public static void setProperty(String key, String value) {
+        properties.get().setProperty(key, value);
+    }
+
+    public static void clearProperty(String key) {
+        properties.get().remove(key);
+    }
+
+    public static void reset() {
+        properties.remove();
+    }
+}
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaInflectorServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaInflectorServerCodegen.java
index 30b0474315864108507f10e0567f34df3238631b..160cbde851f5db1fded5b04a8564a9106856da8d 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaInflectorServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaInflectorServerCodegen.java
@@ -25,6 +25,7 @@ import org.openapitools.codegen.CodegenOperation;
 import org.openapitools.codegen.CodegenProperty;
 import org.openapitools.codegen.CodegenType;
 import org.openapitools.codegen.SupportingFile;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,8 +60,8 @@ public class JavaInflectorServerCodegen extends AbstractJavaCodegen {
         apiDocTemplateFiles.remove("api_doc.mustache");
 
 
-        apiPackage = System.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
-        modelPackage = System.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
+        apiPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.apipackage", "org.openapitools.controllers");
+        modelPackage = GeneratorProperties.getProperty("swagger.codegen.inflector.modelpackage", "org.openapitools.model");
 
         additionalProperties.put("title", title);
         // java inflector uses the jackson lib
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaUndertowServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaUndertowServerCodegen.java
index 5c602bf2ca2ee3177fdd3616cb2ecb3cab5dbb3a..33a6880e8b93dae461f7dc589c22b225ceb47259 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaUndertowServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/JavaUndertowServerCodegen.java
@@ -23,6 +23,7 @@ import org.openapitools.codegen.CodegenOperation;
 import org.openapitools.codegen.CodegenProperty;
 import org.openapitools.codegen.CodegenType;
 import org.openapitools.codegen.SupportingFile;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -54,17 +55,17 @@ public class JavaUndertowServerCodegen extends AbstractJavaCodegen {
         modelDocTemplateFiles.remove("model_doc.mustache");
         apiDocTemplateFiles.remove("api_doc.mustache");
 
-        if(System.getProperty("swagger.codegen.undertow.apipackage") != null && System.getProperty("openapi.codegen.undertow.apipackage") == null) {
+        if(GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage") == null) {
             LOGGER.warn("System property 'swagger.codegen.undertow.apipackage' was renamed to 'swagger.codegen.undertow.apipackage'");
-            apiPackage = System.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
+            apiPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.apipackage", "org.openapitools.handler");
         } else {
-            apiPackage = System.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
+            apiPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.apipackage", "org.openapitools.handler");
         }
-        if(System.getProperty("swagger.codegen.undertow.modelpackage") != null && System.getProperty("openapi.codegen.undertow.modelpackage") == null) {
+        if(GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage") != null && GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage") == null) {
             LOGGER.warn("System property 'swagger.codegen.undertow.modelpackage' was renamed to 'openapi.codegen.undertow.modelpackage'");
-            modelPackage = System.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
+            modelPackage = GeneratorProperties.getProperty("swagger.codegen.undertow.modelpackage", "org.openapitools.model");
         } else {
-            modelPackage = System.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
+            modelPackage = GeneratorProperties.getProperty("openapi.codegen.undertow.modelpackage", "org.openapitools.model");
         }
 
         additionalProperties.put("title", title);
diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSServerCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSServerCodegen.java
index d9260bce92858e8dc8528d8e6eee9ee5a70f702b..7bde3ebdb657d0a2ce0ee67818ba60330399ba28 100644
--- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSServerCodegen.java
+++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/NodeJSServerCodegen.java
@@ -34,6 +34,7 @@ import org.openapitools.codegen.CodegenResponse;
 import org.openapitools.codegen.CodegenType;
 import org.openapitools.codegen.DefaultCodegen;
 import org.openapitools.codegen.SupportingFile;
+import org.openapitools.codegen.config.GeneratorProperties;
 import org.openapitools.codegen.utils.URLPathUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -351,7 +352,7 @@ public class NodeJSServerCodegen extends DefaultCodegen implements CodegenConfig
         }
         writeOptional(outputFolder, new SupportingFile("package.mustache", "", "package.json"));
         writeOptional(outputFolder, new SupportingFile("README.mustache", "", "README.md"));
-        if (System.getProperty("noservice") == null) {
+        if (GeneratorProperties.getProperty("noservice") == null) {
             apiTemplateFiles.put(
                     "service.mustache",   // the template to use
                     "Service.js");       // the extension for each file to write