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 5155526a4d362c62747518cadf794dba7fe8b9b9..492539bbf89d264dd2f9a36a747eea08dddecc6e 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
@@ -2615,35 +2615,47 @@ public class DefaultCodegen implements CodegenConfig {
     }
 
     private void setAddProps(Schema schema, IJsonSchemaValidationProperties property){
+        if (schema.equals(new Schema())) {
+            // if we are trying to set additionalProperties on an empty schema stop recursing
+            return;
+        }
+        boolean additionalPropertiesIsAnyType = false;
         CodegenModel m = null;
         if (property instanceof CodegenModel) {
             m = (CodegenModel) property;
         }
+        CodegenProperty addPropProp = null;
         boolean isAdditionalPropertiesTrue = false;
         if (schema.getAdditionalProperties() == null) {
             if (!disallowAdditionalPropertiesIfNotPresent) {
                 isAdditionalPropertiesTrue = true;
-                CodegenProperty cp = fromProperty("",  new Schema());
-                property.setAdditionalProperties(cp);
-                property.setAdditionalPropertiesIsAnyType(true);
+                addPropProp = fromProperty("",  new Schema());
+                additionalPropertiesIsAnyType = true;
             }
         } else if (schema.getAdditionalProperties() instanceof Boolean) {
             if (Boolean.TRUE.equals(schema.getAdditionalProperties())) {
                 isAdditionalPropertiesTrue = true;
-                CodegenProperty cp = fromProperty("", new Schema());
-                property.setAdditionalProperties(cp);
-                property.setAdditionalPropertiesIsAnyType(true);
+                addPropProp = fromProperty("", new Schema());
+                additionalPropertiesIsAnyType = true;
             }
         } else {
-            CodegenProperty cp = fromProperty("", (Schema) schema.getAdditionalProperties());
-            property.setAdditionalProperties(cp);
+            addPropProp = fromProperty("", (Schema) schema.getAdditionalProperties());
             if (isAnyTypeSchema((Schema) schema.getAdditionalProperties())) {
-                property.setAdditionalPropertiesIsAnyType(true);
+                additionalPropertiesIsAnyType = true;
             }
         }
+        if (additionalPropertiesIsAnyType) {
+            property.setAdditionalPropertiesIsAnyType(true);
+        }
         if (m != null && isAdditionalPropertiesTrue) {
             m.isAdditionalPropertiesTrue = true;
         }
+        if (ModelUtils.isComposedSchema(schema) && !supportsAdditionalPropertiesWithComposedSchema) {
+            return;
+        }
+        if (addPropProp != null) {
+            property.setAdditionalProperties(addPropProp);
+        }
     }
 
 
@@ -6157,6 +6169,7 @@ public class DefaultCodegen implements CodegenConfig {
     }
 
     private void addVarsRequiredVarsAdditionalProps(Schema schema, IJsonSchemaValidationProperties property){
+        setAddProps(schema, property);
         if (!"object".equals(schema.getType())) {
             return;
         }
@@ -6178,7 +6191,6 @@ public class DefaultCodegen implements CodegenConfig {
                 property.setHasRequired(true);
             }
         }
-        setAddProps(schema, property);
     }
 
     private void addJsonSchemaForBodyRequestInCaseItsNotPresent(CodegenParameter codegenParameter, RequestBody body) {
diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
index 17c5864fe008bc58a2f437be4d7254fb76b2fac5..24eb9b6db898e532da2e562091f6576dca925521 100644
--- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
+++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java
@@ -240,7 +240,8 @@ public class DefaultCodegenTest {
     }
 
     @Test
-    public void testAdditionalPropertiesV2Spec() {
+    public void testAdditionalPropertiesV2SpecDisallowAdditionalPropertiesIfNotPresentTrue() {
+        // this is the legacy config that most of our tooling uses
         OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/additional-properties-for-testing.yaml");
         DefaultCodegen codegen = new DefaultCodegen();
         codegen.setOpenAPI(openAPI);
@@ -254,111 +255,269 @@ public class DefaultCodegenTest {
         // 'additionalProperties' keyword for this model, hence assert the value to be null.
         Assert.assertNull(addProps);
         CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", schema);
+        Assert.assertNull(cm.getAdditionalProperties());
         // When the 'additionalProperties' keyword is not present, the model
         // should allow undeclared properties. However, due to bug
         // https://github.com/swagger-api/swagger-parser/issues/1369, the swagger
         // converter does not retain the value of the additionalProperties.
 
-        Map<String, Schema> m = schema.getProperties();
-        Schema child = m.get("map_string");
+        Map<String, Schema> modelPropSchems = schema.getProperties();
+        Schema map_string_sc = modelPropSchems.get("map_string");
+        CodegenProperty map_string_cp = null;
+        Schema map_with_additional_properties_sc = modelPropSchems.get("map_with_additional_properties");
+        CodegenProperty map_with_additional_properties_cp = null;
+        Schema map_without_additional_properties_sc = modelPropSchems.get("map_without_additional_properties");;
+        CodegenProperty map_without_additional_properties_cp = null;
+
+        for(CodegenProperty cp: cm.vars) {
+            if (cp.baseName.equals("map_string")) {
+                map_string_cp = cp;
+            } else if (cp.baseName.equals("map_with_additional_properties")) {
+                map_with_additional_properties_cp = cp;
+            } else if (cp.baseName.equals("map_without_additional_properties")) {
+                map_without_additional_properties_cp = cp;
+            }
+        }
+
+        // map_string
         // This property has the following inline schema.
         // additionalProperties:
         //   type: string
-        Assert.assertNotNull(child);
-        Assert.assertNotNull(child.getAdditionalProperties());
+        Assert.assertNotNull(map_string_sc);
+        Assert.assertNotNull(map_string_sc.getAdditionalProperties());
+        Assert.assertNotNull(map_string_cp.getAdditionalProperties());
 
-        child = m.get("map_with_additional_properties");
+        // map_with_additional_properties
         // This property has the following inline schema.
         // additionalProperties: true
-        Assert.assertNotNull(child);
+        Assert.assertNotNull(map_with_additional_properties_sc);
         // It is unfortunate that child.getAdditionalProperties() returns null for a V2 schema.
         // We cannot differentiate between 'additionalProperties' not present and
         // additionalProperties: true.
-        Assert.assertNull(child.getAdditionalProperties());
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNull(map_with_additional_properties_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_additional_properties_sc);
         Assert.assertNull(addProps);
+        Assert.assertNull(map_with_additional_properties_cp.getAdditionalProperties());
 
-        child = m.get("map_without_additional_properties");
+        // map_without_additional_properties
         // This property has the following inline schema.
         // additionalProperties: false
-        Assert.assertNotNull(child);
+        Assert.assertNotNull(map_without_additional_properties_sc);
         // It is unfortunate that child.getAdditionalProperties() returns null for a V2 schema.
         // We cannot differentiate between 'additionalProperties' not present and
         // additionalProperties: false.
-        Assert.assertNull(child.getAdditionalProperties());
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNull(map_without_additional_properties_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_without_additional_properties_sc);
         Assert.assertNull(addProps);
+        Assert.assertNull(map_without_additional_properties_cp.getAdditionalProperties());
+
+        // check of composed schema model
+        String schemaName = "Parent";
+        schema = openAPI.getComponents().getSchemas().get(schemaName);
+        cm = codegen.fromModel(schemaName, schema);
+        Assert.assertNull(cm.getAdditionalProperties());
     }
 
     @Test
-    public void testAdditionalPropertiesV3Spec() {
+    public void testAdditionalPropertiesV2SpecDisallowAdditionalPropertiesIfNotPresentFalse() {
+        OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/2_0/additional-properties-for-testing.yaml");
+        DefaultCodegen codegen = new DefaultCodegen();
+        codegen.setOpenAPI(openAPI);
+        codegen.setDisallowAdditionalPropertiesIfNotPresent(false);
+        codegen.supportsAdditionalPropertiesWithComposedSchema = true;
+        /*
+        When this DisallowAdditionalPropertiesIfNotPresent is false:
+        for CodegenModel/CodegenParameter/CodegenProperty/CodegenResponse.getAdditionalProperties
+        if the input additionalProperties is False or unset (null)
+        .getAdditionalProperties is set to AnyTypeSchema
+
+        For the False value this is incorrect, but it is the best that we can do because of this bug:
+        https://github.com/swagger-api/swagger-parser/issues/1369 where swagger parser
+        sets both null/False additionalProperties to null
+         */
+
+        Schema schema = openAPI.getComponents().getSchemas().get("AdditionalPropertiesClass");
+        Assert.assertEquals(schema.getAdditionalProperties(), null);
+
+        Schema addProps = ModelUtils.getAdditionalProperties(openAPI, schema);
+        // The petstore-with-fake-endpoints-models-for-testing.yaml does not set the
+        // 'additionalProperties' keyword for this model, hence assert the value to be null.
+        Assert.assertNull(addProps);
+        CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", schema);
+        Assert.assertNotNull(cm.getAdditionalProperties());
+        // When the 'additionalProperties' keyword is not present, the model
+        // should allow undeclared properties. However, due to bug
+        // https://github.com/swagger-api/swagger-parser/issues/1369, the swagger
+        // converter does not retain the value of the additionalProperties.
+
+        Map<String, Schema> modelPropSchems = schema.getProperties();
+        Schema map_string_sc = modelPropSchems.get("map_string");
+        CodegenProperty map_string_cp = null;
+        Schema map_with_additional_properties_sc = modelPropSchems.get("map_with_additional_properties");
+        CodegenProperty map_with_additional_properties_cp = null;
+        Schema map_without_additional_properties_sc = modelPropSchems.get("map_without_additional_properties");;
+        CodegenProperty map_without_additional_properties_cp = null;
+
+        for(CodegenProperty cp: cm.vars) {
+            if (cp.baseName.equals("map_string")) {
+                map_string_cp = cp;
+            } else if (cp.baseName.equals("map_with_additional_properties")) {
+                map_with_additional_properties_cp = cp;
+            } else if (cp.baseName.equals("map_without_additional_properties")) {
+                map_without_additional_properties_cp = cp;
+            }
+        }
+
+        // map_string
+        // This property has the following inline schema.
+        // additionalProperties:
+        //   type: string
+        Assert.assertNotNull(map_string_sc);
+        Assert.assertNotNull(map_string_sc.getAdditionalProperties());
+        Assert.assertNotNull(map_string_cp.getAdditionalProperties());
+
+        // map_with_additional_properties
+        // This property has the following inline schema.
+        // additionalProperties: true
+        Assert.assertNotNull(map_with_additional_properties_sc);
+        // It is unfortunate that child.getAdditionalProperties() returns null for a V2 schema.
+        // We cannot differentiate between 'additionalProperties' not present and
+        // additionalProperties: true.
+        Assert.assertNull(map_with_additional_properties_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_additional_properties_sc);
+        Assert.assertNull(addProps);
+        Assert.assertNotNull(map_with_additional_properties_cp.getAdditionalProperties());
+
+        // map_without_additional_properties
+        // This property has the following inline schema.
+        // additionalProperties: false
+        Assert.assertNotNull(map_without_additional_properties_sc);
+        // It is unfortunate that child.getAdditionalProperties() returns null for a V2 schema.
+        // We cannot differentiate between 'additionalProperties' not present and
+        // additionalProperties: false.
+        Assert.assertNull(map_without_additional_properties_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_without_additional_properties_sc);
+        Assert.assertNull(addProps);
+        Assert.assertNotNull(map_without_additional_properties_cp.getAdditionalProperties());
+
+        // check of composed schema model
+        String schemaName = "Parent";
+        schema = openAPI.getComponents().getSchemas().get(schemaName);
+        cm = codegen.fromModel(schemaName, schema);
+        Assert.assertNotNull(cm.getAdditionalProperties());
+    }
+
+    @Test
+    public void testAdditionalPropertiesV3SpecDisallowAdditionalPropertiesIfNotPresentFalse() {
         OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/python/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml");
         DefaultCodegen codegen = new DefaultCodegen();
         codegen.setDisallowAdditionalPropertiesIfNotPresent(false);
+        codegen.supportsAdditionalPropertiesWithComposedSchema = true;
         codegen.setOpenAPI(openAPI);
 
-        Schema schema = openAPI.getComponents().getSchemas().get("AdditionalPropertiesClass");
-        Assert.assertNull(schema.getAdditionalProperties());
+        Schema componentSchema = openAPI.getComponents().getSchemas().get("AdditionalPropertiesClass");
+        Assert.assertNull(componentSchema.getAdditionalProperties());
 
         // When the 'additionalProperties' keyword is not present, the schema may be
         // extended with any undeclared properties.
-        Schema addProps = ModelUtils.getAdditionalProperties(openAPI, schema);
+        Schema addProps = ModelUtils.getAdditionalProperties(openAPI, componentSchema);
         Assert.assertNotNull(addProps);
         Assert.assertTrue(addProps instanceof ObjectSchema);
-        CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", schema);
+        CodegenModel cm = codegen.fromModel("AdditionalPropertiesClass", componentSchema);
+        Assert.assertNotNull(cm.getAdditionalProperties());
+
+        Map<String, Schema> modelPropSchems = componentSchema.getProperties();
+        Schema map_with_undeclared_properties_string_sc = modelPropSchems.get("map_with_undeclared_properties_string");
+        CodegenProperty map_with_undeclared_properties_string_cp = null;
+        Schema map_with_undeclared_properties_anytype_1_sc = modelPropSchems.get("map_with_undeclared_properties_anytype_1");
+        CodegenProperty map_with_undeclared_properties_anytype_1_cp = null;
+        Schema map_with_undeclared_properties_anytype_2_sc = modelPropSchems.get("map_with_undeclared_properties_anytype_2");
+        CodegenProperty map_with_undeclared_properties_anytype_2_cp = null;
+        Schema map_with_undeclared_properties_anytype_3_sc = modelPropSchems.get("map_with_undeclared_properties_anytype_3");
+        CodegenProperty map_with_undeclared_properties_anytype_3_cp = null;
+        Schema empty_map_sc = modelPropSchems.get("empty_map");
+        CodegenProperty empty_map_cp = null;
+
+        for(CodegenProperty cp: cm.vars) {
+            if (cp.baseName.equals("map_with_undeclared_properties_string")) {
+                map_with_undeclared_properties_string_cp = cp;
+            } else if (cp.baseName.equals("map_with_undeclared_properties_anytype_1")) {
+                map_with_undeclared_properties_anytype_1_cp = cp;
+            } else if (cp.baseName.equals("map_with_undeclared_properties_anytype_2")) {
+                map_with_undeclared_properties_anytype_2_cp = cp;
+            } else if (cp.baseName.equals("map_with_undeclared_properties_anytype_3")) {
+                map_with_undeclared_properties_anytype_3_cp = cp;
+            } else if (cp.baseName.equals("empty_map")) {
+                empty_map_cp = cp;
+            }
+        }
 
-        Map<String, Schema> m = schema.getProperties();
-        Schema child = m.get("map_with_undeclared_properties_string");
+        // map_with_undeclared_properties_string
         // This property has the following inline schema.
         // additionalProperties:
         //   type: string
-        Assert.assertNotNull(child);
-        Assert.assertNotNull(child.getAdditionalProperties());
+        Assert.assertNotNull(map_with_undeclared_properties_string_sc);
+        Assert.assertNotNull(map_with_undeclared_properties_string_sc.getAdditionalProperties());
+        Assert.assertNotNull(map_with_undeclared_properties_string_cp.getAdditionalProperties());
 
-        child = m.get("map_with_undeclared_properties_anytype_1");
+        // map_with_undeclared_properties_anytype_1
         // This property does not use the additionalProperties keyword,
         // which means by default undeclared properties are allowed.
-        Assert.assertNotNull(child);
-        Assert.assertNull(child.getAdditionalProperties());
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_1_sc);
+        Assert.assertNull(map_with_undeclared_properties_anytype_1_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_1_sc);
         Assert.assertNotNull(addProps);
         Assert.assertTrue(addProps instanceof ObjectSchema);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_1_cp.getAdditionalProperties());
 
-        child = m.get("map_with_undeclared_properties_anytype_2");
+        // map_with_undeclared_properties_anytype_2
         // This property does not use the additionalProperties keyword,
         // which means by default undeclared properties are allowed.
-        Assert.assertNotNull(child);
-        Assert.assertNull(child.getAdditionalProperties());
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_2_sc);
+        Assert.assertNull(map_with_undeclared_properties_anytype_2_sc.getAdditionalProperties());
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_2_sc);
         Assert.assertNotNull(addProps);
         Assert.assertTrue(addProps instanceof ObjectSchema);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_2_cp.getAdditionalProperties());
 
-        child = m.get("map_with_undeclared_properties_anytype_3");
+        // map_with_undeclared_properties_anytype_3
         // This property has the following inline schema.
         // additionalProperties: true
-        Assert.assertNotNull(child);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_3_sc);
         // Unlike the V2 spec, in V3 we CAN differentiate between 'additionalProperties' not present and
         // additionalProperties: true.
-        Assert.assertNotNull(child.getAdditionalProperties());
-        Assert.assertEquals(child.getAdditionalProperties(), Boolean.TRUE);
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_3_sc.getAdditionalProperties());
+        Assert.assertEquals(map_with_undeclared_properties_anytype_3_sc.getAdditionalProperties(), Boolean.TRUE);
+        addProps = ModelUtils.getAdditionalProperties(openAPI, map_with_undeclared_properties_anytype_3_sc);
         Assert.assertNotNull(addProps);
         Assert.assertTrue(addProps instanceof ObjectSchema);
+        Assert.assertNotNull(map_with_undeclared_properties_anytype_3_cp.getAdditionalProperties());
 
-        child = m.get("empty_map");
+        // empty_map
         // This property has the following inline schema.
         // additionalProperties: false
-        Assert.assertNotNull(child);
+        Assert.assertNotNull(empty_map_sc);
         // Unlike the V2 spec, in V3 we CAN differentiate between 'additionalProperties' not present and
         // additionalProperties: false.
-        Assert.assertNotNull(child.getAdditionalProperties());
-        Assert.assertEquals(child.getAdditionalProperties(), Boolean.FALSE);
-        addProps = ModelUtils.getAdditionalProperties(openAPI, child);
+        Assert.assertNotNull(empty_map_sc.getAdditionalProperties());
+        Assert.assertEquals(empty_map_sc.getAdditionalProperties(), Boolean.FALSE);
+        addProps = ModelUtils.getAdditionalProperties(openAPI, empty_map_sc);
         Assert.assertNull(addProps);
+        Assert.assertNull(empty_map_cp.getAdditionalProperties());
+
+        // check of composed schema model
+        String schemaName = "SomeObject";
+        Schema schema = openAPI.getComponents().getSchemas().get(schemaName);
+        cm = codegen.fromModel(schemaName, schema);
+        Assert.assertNotNull(cm.getAdditionalProperties());
     }
 
     @Test
-    public void testAdditionalPropertiesV3SpecLegacy() {
+    public void testAdditionalPropertiesV3SpecDisallowAdditionalPropertiesIfNotPresentTrue() {
+        // As per OAS spec, when the 'additionalProperties' keyword is not present, the schema may be
+        // extended with any undeclared properties.
+        // However, in legacy 'additionalProperties' mode, this is interpreted as
+        // 'no additional properties are allowed'.
         OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/petstore-with-fake-endpoints-models-for-testing-with-http-signature.yaml");
         DefaultCodegen codegen = new DefaultCodegen();
         codegen.setDisallowAdditionalPropertiesIfNotPresent(true);
@@ -367,10 +526,6 @@ public class DefaultCodegenTest {
         Schema schema = openAPI.getComponents().getSchemas().get("AdditionalPropertiesClass");
         Assert.assertNull(schema.getAdditionalProperties());
 
-        // As per OAS spec, when the 'additionalProperties' keyword is not present, the schema may be
-        // extended with any undeclared properties.
-        // However, in legacy 'additionalProperties' mode, this is interpreted as
-        // 'no additional properties are allowed'.
         Schema addProps = ModelUtils.getAdditionalProperties(openAPI, schema);
         Assert.assertNull(addProps);
     }
diff --git a/modules/openapi-generator/src/test/resources/2_0/additional-properties-for-testing.yaml b/modules/openapi-generator/src/test/resources/2_0/additional-properties-for-testing.yaml
index 5cfa74c27c8ff7155a93e7df274f85133b124a37..2864ab034c22c60db9ff103fe8680ff1c4241f10 100644
--- a/modules/openapi-generator/src/test/resources/2_0/additional-properties-for-testing.yaml
+++ b/modules/openapi-generator/src/test/resources/2_0/additional-properties-for-testing.yaml
@@ -9,6 +9,18 @@ info:
 host: petstore.swagger.io:80
 basePath: /v2
 definitions:
+  Grandparent:
+    type: object
+    properties:
+      radioWaves:
+        type: boolean
+  Parent:
+    allOf:
+      - $ref: '#/definitions/Grandparent'
+      - type: object
+        properties:
+          teleVision:
+            type: boolean
   AdditionalPropertiesClass:
     type: object
     properties: