Repository: microsoft/kiota (csharp)

Issue:
Schema object allOf requires type
If a schema object uses `allOf` and includes an inline schema definition, but that inline definition doesn't specify `type`, then the inline definition is ignored (in java generation at least).

Minimal example:

```yaml
openapi: 3.0.3
servers:
  - url: 'https://example.com'
info:
  title: example
  version: 0.0.1
paths:
  /path:
    post:
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/outerPayload'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                type: string

components:
  schemas:
    outerPayload:
      allOf:
        - $ref: '#/components/schemas/innerPayload'
        - properties:
            someField:
              type: string
    innerPayload:
      properties:
        anotherField:
          type: string
```

### Steps to reproduce

Run command: `kiota generate --language java -n 'test'`
Version: `1.10.1` (docker container mcr.microsoft.com/openapi/kiota)

### Expected behaviour

A class `test.OuterPayload` should be generated with fields `someField` and `anotherField` and matching setter methods (note `anotherField` is in a superclass).

### Actual behaviour

Only `anotherField` appears; `someField` is not generated.
No errors or warnings are logged - the fields/methods are simply missing in the generated java code.

### Workaround

In the inline schema definition, include `type: object`.
Of course this is only possible if you are in control of the schema in use - so in most cases this workaround won't work.

### Notes

I believe the above document is valid according to the OpenAPI spec. In all other situations, the `type` appears to default to `object` and it does not need to be specified explicitly. For example, in `innerPayload` in the example above, `type: object` is not required. It appears only to be within `allOf` that `type: object` is required.

Pull request:
fixes #4325
fixes #4346
fixes #4074
fixes https://github.com/microsoft/kiota/issues/4428

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1933fa4a87..88fbc334d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -27,6 +27,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Put opening brace after property definition on new line, if property has getter and setter [#4625](https://github.com/microsoft/kiota/issues/4625)
 - Put spaces correctly around dictionary entries [#4625](https://github.com/microsoft/kiota/issues/4625)
 - Remove trailing space after class definition [#4625](https://github.com/microsoft/kiota/issues/4625)
+- Fixed a bug where multiple allOf entries type would not get merged if they were part of a discriminator. [#4325](https://github.com/microsoft/kiota/issues/4325)
+- Fixed a bug where allOf structure with one entry and properties would not be considered as inheritance case. [#4346](https://github.com/microsoft/kiota/issues/4346)
+- Fixed a bug where some allOf scenarios would be missing properties if type object wasn't set on the schema. [#4074](https://github.com/microsoft/kiota/issues/4074)
+- Fixed a bug where schema with multiple allOf entries would incorrectly get merged to inherit from the first entry [#4428] (https://github.com/microsoft/kiota/issues/4428)
 - Fixes constructor generation for nullable properties that are initialized as null in C#,Java and PHP
 
 ## [1.14.0] - 2024-05-02
diff --git a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
index 4c705bdeeb..17a67c842c 100644
--- a/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
+++ b/src/Kiota.Builder/Extensions/OpenApiSchemaExtensions.cs
@@ -10,41 +10,37 @@ public static class OpenApiSchemaExtensions
 {
     private static readonly Func<OpenApiSchema, IList<OpenApiSchema>> classNamesFlattener = x =>
     (x.AnyOf ?? Enumerable.Empty<OpenApiSchema>()).Union(x.AllOf).Union(x.OneOf).ToList();
-    public static IEnumerable<string> GetSchemaNames(this OpenApiSchema schema)
+    public static IEnumerable<string> GetSchemaNames(this OpenApiSchema schema, bool directOnly = false)
     {
         if (schema == null)
-            return Enumerable.Empty<string>();
-        if (schema.Items != null)
+            return [];
+        if (!directOnly && schema.Items != null)
             return schema.Items.GetSchemaNames();
         if (!string.IsNullOrEmpty(schema.Reference?.Id))
-            return new[] { schema.Reference.Id.Split('/')[^1].Split('.')[^1] };
-        if (schema.AnyOf.Any())
+            return [schema.Reference.Id.Split('/')[^1].Split('.')[^1]];
+        if (!directOnly && schema.AnyOf.Any())
             return schema.AnyOf.FlattenIfRequired(classNamesFlattener);
-        if (schema.AllOf.Any())
+        if (!directOnly && schema.AllOf.Any())
             return schema.AllOf.FlattenIfRequired(classNamesFlattener);
-        if (schema.OneOf.Any())
+        if (!directOnly && schema.OneOf.Any())
             return schema.OneOf.FlattenIfRequired(classNamesFlattener);
-        if (!string.IsNullOrEmpty(schema.Title))
-            return new[] { schema.Title };
-        if (!string.IsNullOrEmpty(schema.Xml?.Name))
-            return new[] { schema.Xml.Name };
-        return Enumerable.Empty<string>();
+        return [];
     }
     internal static IEnumerable<OpenApiSchema> FlattenSchemaIfRequired(this IList<OpenApiSchema> schemas, Func<OpenApiSchema, IList<OpenApiSchema>> subsequentGetter)
     {
-        if (schemas is null) return Enumerable.Empty<OpenApiSchema>();
-        return schemas.Count == 1 ?
+        if (schemas is null) return [];
+        return schemas.Count == 1 && !schemas[0].HasAnyProperty() ?
                     schemas.FlattenEmptyEntries(subsequentGetter, 1) :
                     schemas;
     }
     private static IEnumerable<string> FlattenIfRequired(this IList<OpenApiSchema> schemas, Func<OpenApiSchema, IList<OpenApiSchema>> subsequentGetter)
     {
-        return schemas.FlattenSchemaIfRequired(subsequentGetter).Where(static x => !string.IsNullOrEmpty(x.Title)).Select(static x => x.Title);
+        return schemas.FlattenSchemaIfRequired(subsequentGetter).SelectMany(static x => x.GetSchemaNames());
     }
 
-    public static string GetSchemaName(this OpenApiSchema schema)
+    public static string GetSchemaName(this OpenApiSchema schema, bool directOnly = false)
     {
-        return schema.GetSchemaNames().LastOrDefault()?.TrimStart('$') ?? string.Empty;// OData $ref
+        return schema.GetSchemaNames(directOnly).LastOrDefault()?.TrimStart('$') ?? string.Empty;// OData $ref
     }
 
     public static bool IsReferencedSchema(this OpenApiSchema schema)
@@ -61,13 +57,17 @@ public static bool IsArray(this OpenApiSchema? schema)
             (schema.Items.IsComposedEnum() ||
             schema.Items.IsEnum() ||
             schema.Items.IsSemanticallyMeaningful() ||
-            FlattenEmptyEntries(new OpenApiSchema[] { schema.Items }, static x => x.AnyOf.Union(x.AllOf).Union(x.OneOf).ToList(), 1).FirstOrDefault() is OpenApiSchema flat && flat.IsSemanticallyMeaningful());
+            FlattenEmptyEntries([schema.Items], static x => x.AnyOf.Union(x.AllOf).Union(x.OneOf).ToList(), 1).FirstOrDefault() is OpenApiSchema flat && flat.IsSemanticallyMeaningful());
     }
 
-    public static bool IsObject(this OpenApiSchema? schema)
+    public static bool IsObjectType(this OpenApiSchema? schema)
     {
         return "object".Equals(schema?.Type, StringComparison.OrdinalIgnoreCase);
     }
+    public static bool HasAnyProperty(this OpenApiSchema? schema)
+    {
+        return schema?.Properties is { Count: > 0 };
+    }
     public static bool IsInclusiveUnion(this OpenApiSchema? schema)
     {
         return schema?.AnyOf?.Count(static x => IsSemanticallyMeaningful(x, true)) > 1;
@@ -77,25 +77,33 @@ public static bool IsInclusiveUnion(this OpenApiSchema? schema)
     public static bool IsInherited(this OpenApiSchema? schema)
     {
         if (schema is null) return false;
-        var meaningfulSchemas = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf).Where(static x => x.IsSemanticallyMeaningful()).ToArray();
-        return meaningfulSchemas.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) == 1 && meaningfulSchemas.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) == 1;
+        var meaningfulMemberSchemas = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf).Where(static x => x.IsSemanticallyMeaningful()).ToArray();
+        var isRootSchemaMeaningful = schema.IsSemanticallyMeaningful();
+        return meaningfulMemberSchemas.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) == 1 &&
+            (meaningfulMemberSchemas.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) == 1 ||
+            isRootSchemaMeaningful);
     }
 
-    internal static OpenApiSchema? MergeIntersectionSchemaEntries(this OpenApiSchema? schema)
+    internal static OpenApiSchema? MergeIntersectionSchemaEntries(this OpenApiSchema? schema, HashSet<OpenApiSchema>? schemasToExclude = default)
     {
         if (schema is null) return null;
         if (!schema.IsIntersection()) return schema;
         var result = new OpenApiSchema(schema);
         result.AllOf.Clear();
-        var meaningfulSchemas = schema.AllOf.Where(static x => x.IsSemanticallyMeaningful()).Select(MergeIntersectionSchemaEntries).Where(x => x is not null).OfType<OpenApiSchema>();
-        meaningfulSchemas.SelectMany(static x => x.Properties).ToList().ForEach(x => result.Properties.TryAdd(x.Key, x.Value));
+        var meaningfulSchemas = schema.AllOf
+                                    .Where(static x => x.IsSemanticallyMeaningful() || x.AllOf.Any())
+                                    .Select(x => MergeIntersectionSchemaEntries(x, schemasToExclude))
+                                    .Where(x => x is not null && (schemasToExclude is null || !schemasToExclude.Contains(x)))
+                                    .OfType<OpenApiSchema>()
+                                    .ToArray();
+        meaningfulSchemas.FlattenEmptyEntries(static x => x.AllOf).Union(meaningfulSchemas).SelectMany(static x => x.Properties).ToList().ForEach(x => result.Properties.TryAdd(x.Key, x.Value));
         return result;
     }
 
     public static bool IsIntersection(this OpenApiSchema? schema)
     {
-        var meaningfulSchemas = schema?.AllOf?.Where(static x => x.IsSemanticallyMeaningful());
-        return meaningfulSchemas?.Count() > 3 || meaningfulSchemas?.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) > 1 || meaningfulSchemas?.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) > 1;
+        var meaningfulSchemas = schema?.AllOf?.Where(static x => x.IsSemanticallyMeaningful()).ToArray();
+        return meaningfulSchemas?.Count(static x => !string.IsNullOrEmpty(x.Reference?.Id)) > 1 || meaningfulSchemas?.Count(static x => string.IsNullOrEmpty(x.Reference?.Id)) > 1;
     }
 
     public static bool IsExclusiveUnion(this OpenApiSchema? schema)
@@ -136,7 +144,7 @@ public static bool IsComposedEnum(this OpenApiSchema schema)
     public static bool IsSemanticallyMeaningful(this OpenApiSchema schema, bool ignoreNullableObjects = false)
     {
         if (schema is null) return false;
-        return schema.Properties.Any() ||
+        return schema.HasAnyProperty() ||
                 schema.Enum is { Count: > 0 } ||
                 schema.Items != null ||
                 (!string.IsNullOrEmpty(schema.Type) &&
@@ -171,11 +179,11 @@ public static IEnumerable<string> GetSchemaReferenceIds(this OpenApiSchema schem
             return result.Distinct();
         }
 
-        return Enumerable.Empty<string>();
+        return [];
     }
     private static IEnumerable<OpenApiSchema> FlattenEmptyEntries(this IEnumerable<OpenApiSchema> schemas, Func<OpenApiSchema, IList<OpenApiSchema>> subsequentGetter, int? maxDepth = default)
     {
-        if (schemas == null) return Enumerable.Empty<OpenApiSchema>();
+        if (schemas == null) return [];
         ArgumentNullException.ThrowIfNull(subsequentGetter);
 
         if ((maxDepth ?? 1) <= 0)
@@ -186,7 +194,7 @@ private static IEnumerable<OpenApiSchema> FlattenEmptyEntries(this IEnumerable<O
         foreach (var item in result)
         {
             var subsequentItems = subsequentGetter(item);
-            if (string.IsNullOrEmpty(item.Title) && subsequentItems.Any())
+            if (subsequentItems.Any())
                 permutations.Add(item, subsequentItems.FlattenEmptyEntries(subsequentGetter, maxDepth.HasValue ? --maxDepth : default));
         }
         if (permutations.Count > 0)
diff --git a/src/Kiota.Builder/KiotaBuilder.cs b/src/Kiota.Builder/KiotaBuilder.cs
index ef2920287b..fee259f137 100644
--- a/src/Kiota.Builder/KiotaBuilder.cs
+++ b/src/Kiota.Builder/KiotaBuilder.cs
@@ -1548,43 +1548,56 @@ private CodeType CreateModelDeclarationAndType(OpenApiUrlTreeNode currentNode, O
             TypeDefinition = codeDeclaration,
         };
     }
-    private CodeType CreateInheritedModelDeclaration(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, OpenApiOperation? operation, string classNameSuffix, CodeNamespace codeNamespace, bool isRequestBody)
+    private CodeType CreateInheritedModelDeclarationAndType(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, OpenApiOperation? operation, string classNameSuffix, CodeNamespace codeNamespace, bool isRequestBody, string typeNameForInlineSchema)
     {
-        var allOfs = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf);
-        CodeElement? codeDeclaration = null;
-        var className = string.Empty;
-        var codeNamespaceFromParent = GetShortestNamespace(codeNamespace, schema);
-        foreach (var currentSchema in allOfs)
+        return new CodeType
         {
-            var referenceId = GetReferenceIdFromOriginalSchema(currentSchema, schema);
-            var shortestNamespaceName = GetModelsNamespaceNameFromReferenceId(referenceId);
-            var shortestNamespace = string.IsNullOrEmpty(referenceId) ? codeNamespaceFromParent : rootNamespace?.FindOrAddNamespace(shortestNamespaceName);
-            className = (currentSchema.GetSchemaName() is string cName && !string.IsNullOrEmpty(cName) ?
+            TypeDefinition = CreateInheritedModelDeclaration(currentNode, schema, operation, classNameSuffix, codeNamespace, isRequestBody, typeNameForInlineSchema),
+        };
+    }
+    private CodeClass CreateInheritedModelDeclaration(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, OpenApiOperation? operation, string classNameSuffix, CodeNamespace codeNamespace, bool isRequestBody, string typeNameForInlineSchema)
+    {
+        var flattenedAllOfs = schema.AllOf.FlattenSchemaIfRequired(static x => x.AllOf).ToArray();
+        var referenceId = schema.Reference?.Id;
+        var className = (schema.GetSchemaName(true) is string cName && !string.IsNullOrEmpty(cName) ?
                             cName :
-                            currentNode.GetClassName(config.StructuredMimeTypes, operation: operation, suffix: classNameSuffix, schema: schema, requestBody: isRequestBody))
+                            (!string.IsNullOrEmpty(typeNameForInlineSchema) ?
+                                typeNameForInlineSchema :
+                                currentNode.GetClassName(config.StructuredMimeTypes, operation: operation, suffix: classNameSuffix, schema: schema, requestBody: isRequestBody)))
                         .CleanupSymbolName();
-            if (shortestNamespace != null)
-                codeDeclaration = AddModelDeclarationIfDoesntExist(currentNode, currentSchema, className, shortestNamespace, codeDeclaration as CodeClass);
-        }
-        if (codeDeclaration is CodeClass currentClass &&
-            !currentClass.Documentation.DescriptionAvailable &&
+        var shortestNamespaceName = GetModelsNamespaceNameFromReferenceId(referenceId);
+        var codeNamespaceFromParent = GetShortestNamespace(codeNamespace, schema);
+        if (rootNamespace is null)
+            throw new InvalidOperationException("Root namespace is not set");
+        var shortestNamespace = string.IsNullOrEmpty(referenceId) ? codeNamespaceFromParent : rootNamespace.FindOrAddNamespace(shortestNamespaceName);
+        var inlineSchema = Array.Find(flattenedAllOfs, static x => !x.IsReferencedSchema());
+        var referencedSchema = Array.Find(flattenedAllOfs, static x => x.IsReferencedSchema());
+        var rootSchemaHasProperties = schema.HasAnyProperty();
+        var codeDeclaration = (rootSchemaHasProperties, inlineSchema, referencedSchema) switch
+        {
+            // greatest parent type
+            (true, null, null) => AddModelDeclarationIfDoesntExist(currentNode, schema, className, shortestNamespace),
+            // inline schema + referenced schema
+            (false, not null, not null) => AddModelDeclarationIfDoesntExist(currentNode, inlineSchema, className, shortestNamespace, CreateInheritedModelDeclaration(currentNode, referencedSchema, operation, classNameSuffix, codeNamespace, isRequestBody, string.Empty)),
+            // properties + referenced schema
+            (true, null, not null) => AddModelDeclarationIfDoesntExist(currentNode, schema, className, shortestNamespace, CreateInheritedModelDeclaration(currentNode, referencedSchema, operation, classNameSuffix, codeNamespace, isRequestBody, string.Empty)),
+            // properties + inline schema
+            (true, not null, null) => AddModelDeclarationIfDoesntExist(currentNode, schema, className, shortestNamespace, CreateInheritedModelDeclaration(currentNode, inlineSchema, operation, classNameSuffix, codeNamespace, isRequestBody, typeNameForInlineSchema)),
+            // empty schema + referenced schema
+            (false, null, not null) => AddModelDeclarationIfDoesntExist(currentNode, referencedSchema, className, shortestNamespace),
+            // empty schema + inline schema
+            (false, not null, null) => AddModelDeclarationIfDoesntExist(currentNode, inlineSchema, className, shortestNamespace),
+            // meaningless scenarios
+            (false, null, null) or (true, not null, not null) => throw new InvalidOperationException("invalid inheritance case"),
+
+        };
+        if (codeDeclaration is not CodeClass currentClass) throw new InvalidOperationException("Inheritance is only supported for classes");
+        if (!currentClass.Documentation.DescriptionAvailable &&
             string.IsNullOrEmpty(schema.AllOf.LastOrDefault()?.Description) &&
             !string.IsNullOrEmpty(schema.Description))
             currentClass.Documentation.DescriptionTemplate = schema.Description.CleanupDescription(); // the last allof entry often is not a reference and doesn't have a description.
 
-        return new CodeType
-        {
-            TypeDefinition = codeDeclaration,
-        };
-    }
-    private static string? GetReferenceIdFromOriginalSchema(OpenApiSchema schema, OpenApiSchema parentSchema)
-    {
-        var title = schema.Title;
-        if (!string.IsNullOrEmpty(schema.Reference?.Id)) return schema.Reference.Id;
-        if (string.IsNullOrEmpty(title)) return string.Empty;
-        if (parentSchema.Reference?.Id?.EndsWith(title, StringComparison.OrdinalIgnoreCase) ?? false) return parentSchema.Reference.Id;
-        if (parentSchema.Items?.Reference?.Id?.EndsWith(title, StringComparison.OrdinalIgnoreCase) ?? false) return parentSchema.Items.Reference.Id;
-        return parentSchema.GetSchemaReferenceIds().FirstOrDefault(refId => refId.EndsWith(title, StringComparison.OrdinalIgnoreCase));
+        return currentClass;
     }
     private CodeTypeBase CreateComposedModelDeclaration(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, OpenApiOperation? operation, string suffixForInlineSchema, CodeNamespace codeNamespace, bool isRequestBody, string typeNameForInlineSchema)
     {
@@ -1593,7 +1606,7 @@ private CodeTypeBase CreateComposedModelDeclaration(OpenApiUrlTreeNode currentNo
         if (typesCount == 1 && schema.Nullable && schema.IsInclusiveUnion() || // nullable on the root schema outside of anyOf
             typesCount == 2 && (schema.AnyOf?.Any(static x => // nullable on a schema in the anyOf
                                                         x.Nullable &&
-                                                        !x.Properties.Any() &&
+                                                        !x.HasAnyProperty() &&
                                                         !x.IsExclusiveUnion() &&
                                                         !x.IsInclusiveUnion() &&
                                                         !x.IsInherited() &&
@@ -1672,7 +1685,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
 
         if (schema.IsInherited())
         {
-            return CreateInheritedModelDeclaration(currentNode, schema, operation, suffix, codeNamespace, isRequestBody);
+            return CreateInheritedModelDeclarationAndType(currentNode, schema, operation, suffix, codeNamespace, isRequestBody, typeNameForInlineSchema);
         }
 
         if (schema.IsIntersection() && schema.MergeIntersectionSchemaEntries() is OpenApiSchema mergedSchema)
@@ -1687,7 +1700,7 @@ private CodeTypeBase CreateModelDeclarations(OpenApiUrlTreeNode currentNode, Ope
             return CreateComposedModelDeclaration(currentNode, schema, operation, suffix, codeNamespace, isRequestBody, typeNameForInlineSchema);
         }
 
-        if (schema.IsObject() || schema.Properties.Any() || schema.IsEnum() || !string.IsNullOrEmpty(schema.AdditionalProperties?.Type))
+        if (schema.IsObjectType() || schema.HasAnyProperty() || schema.IsEnum() || !string.IsNullOrEmpty(schema.AdditionalProperties?.Type))
         {
             // no inheritance or union type, often empty definitions with only additional properties are used as property bags.
             return CreateModelDeclarationAndType(currentNode, schema, operation, codeNamespace, suffix, response: responseValue, typeNameForInlineSchema: typeNameForInlineSchema, isRequestBody);
@@ -1736,13 +1749,22 @@ private CodeNamespace GetSearchNamespace(OpenApiUrlTreeNode currentNode, CodeNam
         return currentNamespace;
     }
     private ConcurrentDictionary<string, ModelClassBuildLifecycle> classLifecycles = new(StringComparer.OrdinalIgnoreCase);
-    private CodeElement AddModelDeclarationIfDoesntExist(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, string declarationName, CodeNamespace currentNamespace, CodeClass? inheritsFrom = null)
+    private CodeElement AddModelDeclarationIfDoesntExist(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, string declarationName, CodeNamespace currentNamespace, CodeClass? inheritsFrom = null, OpenApiSchema? parentSchemaToExcludeForIntersections = null)
     {
         if (GetExistingDeclaration(currentNamespace, currentNode, declarationName) is not CodeElement existingDeclaration) // we can find it in the components
         {
             if (AddEnumDeclaration(currentNode, schema, declarationName, currentNamespace) is CodeEnum enumDeclaration)
                 return enumDeclaration;
 
+            if (schema.IsIntersection() &&
+                (parentSchemaToExcludeForIntersections is null ?
+                    schema.MergeIntersectionSchemaEntries() :
+                    schema.MergeIntersectionSchemaEntries([parentSchemaToExcludeForIntersections])) is OpenApiSchema mergedSchema &&
+                AddModelDeclarationIfDoesntExist(currentNode, mergedSchema, declarationName, currentNamespace, inheritsFrom) is CodeClass createdClass)
+            {
+                // multiple allOf entries that do not translate to inheritance
+                return createdClass;
+            }
             return AddModelClass(currentNode, schema, declarationName, currentNamespace, inheritsFrom);
         }
         return existingDeclaration;
@@ -1821,8 +1843,9 @@ private CodeNamespace GetShortestNamespace(CodeNamespace currentNamespace, OpenA
     }
     private CodeClass AddModelClass(OpenApiUrlTreeNode currentNode, OpenApiSchema schema, string declarationName, CodeNamespace currentNamespace, CodeClass? inheritsFrom = null)
     {
-        if (inheritsFrom == null && schema.AllOf.FirstOrDefault(static x => x.Reference != null) is OpenApiSchema parentSchema)
+        if (inheritsFrom == null && schema.AllOf.Where(static x => x.Reference != null).ToArray() is { Length: 1 } referencedSchemas)
         {// any non-reference would be the current class in some description styles
+            var parentSchema = referencedSchemas[0];
             var parentClassNamespace = GetShortestNamespace(currentNamespace, parentSchema);
             inheritsFrom = (CodeClass)AddModelDeclarationIfDoesntExist(currentNode, parentSchema, parentSchema.GetSchemaName().CleanupSymbolName(), parentClassNamespace);
         }
@@ -2065,7 +2088,12 @@ internal static void AddDiscriminatorMethod(CodeClass newClass, string discrimin
         }
         var className = currentNode.GetClassName(config.StructuredMimeTypes, schema: discriminatorSchema).CleanupSymbolName();
         var shouldInherit = discriminatorSchema.AllOf.Any(x => currentSchema.Reference?.Id.Equals(x.Reference?.Id, StringComparison.OrdinalIgnoreCase) ?? false);
-        var codeClass = AddModelDeclarationIfDoesntExist(currentNode, discriminatorSchema, className, GetShortestNamespace(currentNamespace, discriminatorSchema), shouldInherit ? baseClass : null);
+        if (baseClass is not null && shouldInherit && !discriminatorSchema.IsInherited())
+        {
+            logger.LogWarning("Discriminator {ComponentKey} is not inherited from {ClassName}.", componentKey, baseClass.Name);
+            return null;
+        }
+        var codeClass = AddModelDeclarationIfDoesntExist(currentNode, discriminatorSchema, className, GetShortestNamespace(currentNamespace, discriminatorSchema), shouldInherit ? baseClass : null, currentSchema);
         return new CodeType
         {
             TypeDefinition = codeClass,
@@ -2102,7 +2130,7 @@ private Dictionary<string, OpenApiSchema> CollectAllProperties(OpenApiSchema sch
         Dictionary<string, OpenApiSchema> result = schema.Properties?.ToDictionary(static x => x.Key, static x => x.Value, StringComparer.Ordinal) ?? new(StringComparer.Ordinal);
         if (schema.AllOf?.Any() ?? false)
         {
-            foreach (var supProperty in schema.AllOf.Where(static x => x.IsObject() && !x.IsReferencedSchema() && x.Properties is not null).SelectMany(static x => x.Properties))
+            foreach (var supProperty in schema.AllOf.Where(static x => !x.IsReferencedSchema() && x.HasAnyProperty()).SelectMany(static x => x.Properties))
             {
                 result.Add(supProperty.Key, supProperty.Value);
             }
diff --git a/src/Kiota.Builder/Validation/MissingDiscriminator.cs b/src/Kiota.Builder/Validation/MissingDiscriminator.cs
index ad12d74ea2..c889f5cf5a 100644
--- a/src/Kiota.Builder/Validation/MissingDiscriminator.cs
+++ b/src/Kiota.Builder/Validation/MissingDiscriminator.cs
@@ -35,7 +35,7 @@ private static void ValidateSchema(OpenApiSchema schema, IValidationContext cont
     {
         if (!schema.IsInclusiveUnion() && !schema.IsExclusiveUnion())
             return;
-        if (schema.AnyOf.All(static x => !x.IsObject()) && schema.OneOf.All(static x => !x.IsObject()))
+        if (schema.AnyOf.All(static x => !x.IsObjectType()) && schema.OneOf.All(static x => !x.IsObjectType()))
             return;
         if (string.IsNullOrEmpty(schema.GetDiscriminatorPropertyName()) || !schema.GetDiscriminatorMappings(idx).Any())
             context.CreateWarning(nameof(MissingDiscriminator), $"The schema {address} is a polymorphic type but does not define a discriminator. This will result in a serialization errors.");
diff --git a/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs b/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs
index 0257c53902..78a4b31572 100644
--- a/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs
+++ b/src/Kiota.Builder/Validation/UrlFormEncodedComplex.cs
@@ -23,9 +23,9 @@ public UrlFormEncodedComplex() : base(nameof(UrlFormEncodedComplex), static (con
     private static void ValidateSchema(OpenApiSchema schema, IValidationContext context, string operationId, string schemaName)
     {
         if (schema == null) return;
-        if (!schema.IsObject())
+        if (!schema.IsObjectType())
             context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {operationId} has a {schemaName} which is not an object type. This is not supported by Kiota and serialization will fail.");
-        if (schema.Properties.Any(static x => x.Value.IsObject()))
+        if (schema.Properties.Any(static x => x.Value.IsObjectType()))
             context.CreateWarning(nameof(UrlFormEncodedComplex), $"The operation {operationId} has a {schemaName} with a complex properties and the url form encoded content type. This is not supported by Kiota and serialization of complex properties will fail.");
     }
 }


Test patch:
diff --git a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
index 19accd89df..08d46a13c7 100644
--- a/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
+++ b/tests/Kiota.Builder.Tests/Extensions/OpenApiSchemaExtensionsTests.cs
@@ -43,17 +43,19 @@ public void Defensive()
         Assert.False(OpenApiSchemaExtensions.IsInclusiveUnion(null));
         Assert.False(OpenApiSchemaExtensions.IsExclusiveUnion(null));
         Assert.False(OpenApiSchemaExtensions.IsArray(null));
-        Assert.False(OpenApiSchemaExtensions.IsObject(null));
+        Assert.False(OpenApiSchemaExtensions.IsObjectType(null));
+        Assert.False(OpenApiSchemaExtensions.HasAnyProperty(null));
         Assert.False(OpenApiSchemaExtensions.IsReferencedSchema(null));
         Assert.Null(OpenApiSchemaExtensions.MergeIntersectionSchemaEntries(null));
 
         Assert.False(new OpenApiSchema { Reference = null }.IsReferencedSchema());
         Assert.False(new OpenApiSchema { Type = null }.IsArray());
-        Assert.False(new OpenApiSchema { Type = null }.IsObject());
+        Assert.False(new OpenApiSchema { Type = null }.IsObjectType());
         Assert.False(new OpenApiSchema { AnyOf = null }.IsInclusiveUnion());
         Assert.False(new OpenApiSchema { AllOf = null }.IsInherited());
         Assert.False(new OpenApiSchema { AllOf = null }.IsIntersection());
         Assert.False(new OpenApiSchema { OneOf = null }.IsExclusiveUnion());
+        Assert.False(new OpenApiSchema { Properties = null }.HasAnyProperty());
         var original = new OpenApiSchema { AllOf = null };
         Assert.Equal(original, original.MergeIntersectionSchemaEntries());
 
@@ -84,87 +86,205 @@ public void LocalReferencesAreSupported()
         Assert.True(mockSchema.IsReferencedSchema());
     }
     [Fact]
-    public void GetSchemaNameAllOf()
+    public void GetSchemaNameAllOfTitleEmpty()
     {
         var schema = new OpenApiSchema
         {
-            AllOf = new List<OpenApiSchema> {
-                new() {
+            AllOf = [
+                new()
+                {
                     Title = "microsoft.graph.entity"
                 },
-                new() {
+                new()
+                {
                     Title = "microsoft.graph.user"
                 }
-            }
+            ]
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Contains("microsoft.graph.user", names);
-        Assert.Equal("microsoft.graph.user", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
     }
     [Fact]
-    public void GetSchemaNameAllOfNested()
+    public void GetSchemaNameAllOfReference()
     {
         var schema = new OpenApiSchema
         {
-            AllOf = new List<OpenApiSchema> {
-                new() {
-                    AllOf = new List<OpenApiSchema> {
-                        new() {
+            AllOf = [
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.entity"
+                    }
+                },
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.user"
+                    }
+                }
+            ]
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Contains("user", names);
+        Assert.Equal("user", schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameAllOfNestedTitleEmpty()
+    {
+        var schema = new OpenApiSchema
+        {
+            AllOf = [
+                new()
+                {
+                    AllOf = [
+                        new()
+                        {
                             Title = "microsoft.graph.entity"
                         },
-                        new() {
+                        new()
+                        {
                             Title = "microsoft.graph.user"
                         }
-                    }
+                    ]
                 }
-            }
+            ]
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Contains("microsoft.graph.user", names);
-        Assert.Equal("microsoft.graph.user", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
     }
     [Fact]
-    public void GetSchemaNameAnyOf()
+    public void GetSchemaNameAllOfNestedReference()
     {
         var schema = new OpenApiSchema
         {
-            AnyOf = new List<OpenApiSchema> {
-                new() {
+            AllOf = [
+                new()
+                {
+                    AllOf = [
+                        new()
+                        {
+                            Reference = new()
+                            {
+                                Id = "microsoft.graph.entity"
+                            }
+                        },
+                        new()
+                        {
+                            Reference = new()
+                            {
+                                Id = "microsoft.graph.user"
+                            }
+                        }
+                    ]
+                }
+            ]
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Contains("user", names);
+        Assert.Equal("user", schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameAnyOfTitleEmpty()
+    {
+        var schema = new OpenApiSchema
+        {
+            AnyOf = [
+                new()
+                {
                     Title = "microsoft.graph.entity"
                 },
-                new() {
+                new()
+                {
                     Title = "microsoft.graph.user"
                 }
-            }
+            ]
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Contains("microsoft.graph.user", names);
-        Assert.Equal("microsoft.graph.user", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
     }
     [Fact]
-    public void GetSchemaNameOneOf()
+    public void GetSchemaNameAnyOfReference()
     {
         var schema = new OpenApiSchema
         {
-            OneOf = new List<OpenApiSchema> {
-                new() {
+            AnyOf = [
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.entity"
+                    }
+                },
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.user"
+                    }
+                }
+            ]
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Contains("user", names);
+        Assert.Equal("user", schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameOneOfTitleEmpty()
+    {
+        var schema = new OpenApiSchema
+        {
+            OneOf = [
+                new()
+                {
                     Title = "microsoft.graph.entity"
                 },
-                new() {
+                new()
+                {
                     Title = "microsoft.graph.user"
                 }
-            }
+            ]
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Contains("microsoft.graph.user", names);
-        Assert.Equal("microsoft.graph.user", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameOneOfReference()
+    {
+        var schema = new OpenApiSchema
+        {
+            OneOf = [
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.entity"
+                    }
+                },
+                new()
+                {
+                    Reference = new()
+                    {
+                        Id = "microsoft.graph.user"
+                    }
+                }
+            ]
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Contains("user", names);
+        Assert.Equal("user", schema.GetSchemaName());
     }
     [Fact]
-    public void GetSchemaNameItems()
+    public void GetSchemaNameItemsTitleEmpty()
     {
         var schema = new OpenApiSchema
         {
@@ -174,20 +294,51 @@ public void GetSchemaNameItems()
             },
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Equal("microsoft.graph.entity", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameItemsReference()
+    {
+        var schema = new OpenApiSchema
+        {
+            Items = new()
+            {
+                Reference = new()
+                {
+                    Id = "microsoft.graph.entity"
+                }
+            },
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Equal("entity", schema.GetSchemaName());
         Assert.Single(names);
     }
     [Fact]
-    public void GetSchemaNameTitle()
+    public void GetSchemaNameTitleEmpty()
     {
         var schema = new OpenApiSchema
         {
             Title = "microsoft.graph.entity"
         };
         var names = schema.GetSchemaNames();
-        Assert.Contains("microsoft.graph.entity", names);
-        Assert.Equal("microsoft.graph.entity", schema.GetSchemaName());
+        Assert.Empty(names);
+        Assert.Empty(schema.GetSchemaName());
+    }
+    [Fact]
+    public void GetSchemaNameReference()
+    {
+        var schema = new OpenApiSchema
+        {
+            Reference = new()
+            {
+                Id = "microsoft.graph.entity"
+            }
+        };
+        var names = schema.GetSchemaNames();
+        Assert.Contains("entity", names);
+        Assert.Equal("entity", schema.GetSchemaName());
         Assert.Single(names);
     }
     [Fact]
diff --git a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
index 82dabd2d6a..66dd9e4f5f 100644
--- a/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
+++ b/tests/Kiota.Builder.Tests/KiotaBuilderTests.cs
@@ -1878,7 +1878,7 @@ public void Inline_Property_Inheritance_Is_Supported()
                                                             Type = "object",
                                                             Properties = new Dictionary<string, OpenApiSchema> {
                                                                 {
-                                                                    "info", new OpenApiSchema {
+                                                                    "info2", new OpenApiSchema {
                                                                         Type = "object",
                                                                         Properties = new Dictionary<string, OpenApiSchema> {
                                                                             {
@@ -1890,9 +1890,9 @@ public void Inline_Property_Inheritance_Is_Supported()
                                                                     }
                                                                 }
                                                             },
-                                                            AllOf = new List<OpenApiSchema> {
+                                                            AllOf = [
                                                                 resourceSchema,
-                                                            }
+                                                            ]
                                                         }
                                                     }
                                                 }
@@ -1923,12 +1923,12 @@ public void Inline_Property_Inheritance_Is_Supported()
         var itemsNS = codeModel.FindNamespaceByName("ApiSdk.resource.item");
         var responseClass = itemsNS.FindChildByName<CodeClass>("ResourceGetResponse");
         var derivedResourceClass = itemsNS.FindChildByName<CodeClass>("ResourceGetResponse_derivedResource");
-        var derivedResourceInfoClass = itemsNS.FindChildByName<CodeClass>("ResourceGetResponse_derivedResource_info");
+        var derivedResourceInfoClass = itemsNS.FindChildByName<CodeClass>("ResourceGetResponse_derivedResource_info2");
 
 
         Assert.NotNull(resourceClass);
         Assert.NotNull(derivedResourceClass);
-        Assert.NotNull(derivedResourceClass.StartBlock);
+        Assert.NotNull(derivedResourceClass.StartBlock.Inherits);
         Assert.Equal(derivedResourceClass.StartBlock.Inherits.TypeDefinition, resourceClass);
         Assert.NotNull(derivedResourceInfoClass);
         Assert.NotNull(responseClass);
@@ -7396,7 +7396,7 @@ public async Task InheritanceWithAllOfInBaseType()
         Assert.NotNull(codeModel.FindChildByName<CodeClass>("Group"));
     }
     [Fact]
-    public async Task InheritanceWithAllOfWith3Parts()
+    public async Task InheritanceWithAllOfWith3Parts3SchemaChildClass()
     {
         var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
         await using var fs = await GetDocumentStream(@"openapi: 3.0.1
@@ -7411,17 +7411,22 @@ public async Task InheritanceWithAllOfWith3Parts()
     get:
       responses: 
         '200':
-          description: Example response
           content:
             application/json:
               schema:
                 $ref: '#/components/schemas/microsoft.graph.directoryObject'
+  /group:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.group'
 components:
   schemas:
     microsoft.graph.directoryObject:
-      title: 'directoryObject'
       required: ['@odata.type']
-      type: 'object'
       properties:
         '@odata.type':
           type: 'string'
@@ -7429,21 +7434,357 @@ public async Task InheritanceWithAllOfWith3Parts()
       discriminator:
         propertyName: '@odata.type'
         mapping:
-          '#microsoft.graph.user': '#/components/schemas/microsoft.graph.user'
           '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group'
+    microsoft.graph.groupFacet1:
+      properties:
+        facetprop1:
+          type: 'string'
+    microsoft.graph.groupFacet2:
+      properties:
+        facetprop2:
+          type: 'string'
+    microsoft.graph.group:
+      title: 'group'
+      allOf:
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObject'
+        - '$ref': '#/components/schemas/microsoft.graph.groupFacet1'
+        - '$ref': '#/components/schemas/microsoft.graph.groupFacet2'");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var directoryObjectClass = codeModel.FindChildByName<CodeClass>("DirectoryObject");
+        Assert.Null(directoryObjectClass.StartBlock.Inherits);
+        Assert.NotNull(directoryObjectClass);
+        var groupClass = codeModel.FindChildByName<CodeClass>("Group");
+        Assert.NotNull(groupClass);
+        Assert.Equal(4, groupClass.Properties.Count());
+        Assert.Null(groupClass.StartBlock.Inherits);
+        Assert.Single(groupClass.Properties.Where(static x => x.Kind is CodePropertyKind.AdditionalData));
+        Assert.Single(groupClass.Properties.Where(static x => x.Name.Equals("oDataType", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(groupClass.Properties.Where(static x => x.Name.Equals("facetprop1", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(groupClass.Properties.Where(static x => x.Name.Equals("facetprop2", StringComparison.OrdinalIgnoreCase)));
+    }
+    [Fact]
+    public async Task NestedIntersectionTypeAllOf()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.3
+info:
+  title: Model Registry REST API
+  version: v1alpha2
+  description: REST API for Model Registry to create and manage ML model metadata
+  license:
+    name: Apache 2.0
+    url: 'https://www.apache.org/licenses/LICENSE-2.0'
+servers:
+  - url: 'https://localhost:8080'
+  - url: 'http://localhost:8080'
+paths:
+  /api/model_registry/v1alpha2/registered_models:
+    summary: Path used to manage the list of registeredmodels.
+    description: >-
+      The REST endpoint/path used to list and create zero or more `RegisteredModel` entities.  This path contains a `GET` and `POST` operation to perform the list and create tasks, respectively.
+    get:
+      responses:
+        '200':
+          $ref: '#/components/responses/RegisteredModelListResponse'
+      summary: List All RegisteredModels
+      description: Gets a list of all `RegisteredModel` entities.
+components:
+  schemas:
+    BaseResource:
+      type: object
+      properties:
+        id:
+          format: int64
+          description: Output only. The unique server generated id of the resource.
+          type: number
+          readOnly: true
+      allOf:
+        - $ref: '#/components/schemas/BaseResourceCreate'
+    BaseResourceCreate:
+      type: object
+      properties:
+        name:
+          description: |-
+            The client provided name of the artifact. This field is optional. If set,
+            it must be unique among all the artifacts of the same artifact type within
+            a database instance and cannot be changed once set.
+          type: string
+    BaseResourceList:
+      required:
+        - size
+      type: object
+      properties:
+        size:
+          format: int32
+          description: Number of items in result list.
+          type: integer
+    RegisteredModel:
+      description: A registered model in model registry. A registered model has ModelVersion children.
+      allOf:
+        - $ref: '#/components/schemas/BaseResource'
+        - $ref: '#/components/schemas/RegisteredModelCreate'
+    RegisteredModelCreate:
+      description: A registered model in model registry. A registered model has ModelVersion children.
+      allOf:
+        - $ref: '#/components/schemas/BaseResourceCreate'
+    RegisteredModelList:
+      description: List of RegisteredModels.
+      type: object
+      allOf:
+        - $ref: '#/components/schemas/BaseResourceList'
+        - type: object
+          properties:
+            items:
+              description: ''
+              type: array
+              items:
+                $ref: '#/components/schemas/RegisteredModel'
+              readOnly: false
+  responses:
+    RegisteredModelListResponse:
+      content:
+        application/json:
+          schema:
+            $ref: '#/components/schemas/RegisteredModelList'
+      description: A response containing a list of `RegisteredModel` entities.\");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var registeredModelClass = codeModel.FindChildByName<CodeClass>("RegisteredModel");
+        Assert.Null(registeredModelClass.StartBlock.Inherits);
+        Assert.NotNull(registeredModelClass);
+        Assert.Single(registeredModelClass.Properties.Where(static x => x.Kind is CodePropertyKind.AdditionalData));
+        Assert.Single(registeredModelClass.Properties.Where(static x => x.Name.Equals("name", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(registeredModelClass.Properties.Where(static x => x.Name.Equals("id", StringComparison.OrdinalIgnoreCase)));
+    }
+    [Fact]
+    public async Task InheritanceWithAllOfWith3Parts3SchemaParentClass()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.1
+info:
+  title: OData Service for namespace microsoft.graph
+  description: This OData service is located at https://graph.microsoft.com/v1.0
+  version: 1.0.1
+servers:
+  - url: https://graph.microsoft.com/v1.0
+paths:
+  /directoryObject:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.directoryObject'
+  /group:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.group'
+components:
+  schemas:
+    microsoft.graph.directoryObject:
+      required: ['@odata.type']
+      properties:
+        '@odata.type':
+          type: 'string'
+          default: '#microsoft.graph.directoryObject'
+      allOf:
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObjectFacet1'
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObjectFacet2'
+      discriminator:
+        propertyName: '@odata.type'
+        mapping:
+          '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group'
+    microsoft.graph.directoryObjectFacet1:
+      properties:
+        facetprop1:
+          type: 'string'
+    microsoft.graph.directoryObjectFacet2:
+      properties:
+        facetprop2:
+          type: 'string'
     microsoft.graph.group:
+      allOf:
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObject'
+      properties:
+        groupprop1:
+          type: 'string'");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var directoryObjectClass = codeModel.FindChildByName<CodeClass>("DirectoryObject");
+        Assert.NotNull(directoryObjectClass);
+        Assert.Null(directoryObjectClass.StartBlock.Inherits);
+        Assert.Single(directoryObjectClass.Properties.Where(static x => x.Kind is CodePropertyKind.AdditionalData));
+        Assert.Single(directoryObjectClass.Properties.Where(static x => x.Name.Equals("oDataType", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(directoryObjectClass.Properties.Where(static x => x.Name.Equals("facetprop1", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(directoryObjectClass.Properties.Where(static x => x.Name.Equals("facetprop2", StringComparison.OrdinalIgnoreCase)));
+        var groupClass = codeModel.FindChildByName<CodeClass>("Group");
+        Assert.NotNull(groupClass);
+        Assert.Single(groupClass.Properties);
+        Assert.NotNull(groupClass.StartBlock.Inherits);
+        Assert.Empty(groupClass.Properties.Where(static x => x.Kind is CodePropertyKind.AdditionalData));
+        Assert.Empty(groupClass.Properties.Where(static x => x.Name.Equals("oDataType", StringComparison.OrdinalIgnoreCase)));
+        Assert.Empty(groupClass.Properties.Where(static x => x.Name.Equals("facetprop1", StringComparison.OrdinalIgnoreCase)));
+        Assert.Empty(groupClass.Properties.Where(static x => x.Name.Equals("facetprop2", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(groupClass.Properties.Where(static x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase)));
+    }
+    [Fact]
+    public async Task InheritanceWithAllOfWith2Parts1Schema1InlineNoDiscriminator()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.1
+info:
+  title: OData Service for namespace microsoft.graph
+  description: This OData service is located at https://graph.microsoft.com/v1.0
+  version: 1.0.1
+servers:
+  - url: https://graph.microsoft.com/v1.0
+paths:
+  /group:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.group'
+components:
+  schemas:
+    microsoft.graph.directoryObject:
+      title: 'directoryObject'
+      required: ['@odata.type']
+      type: 'object'
+      properties:
+        '@odata.type':
+          type: 'string'
+          default: '#microsoft.graph.directoryObject'
+    microsoft.graph.group:
+      type: 'object'
       allOf:
         - '$ref': '#/components/schemas/microsoft.graph.directoryObject'
         - title: 'group part 1'
           type: 'object'
           properties:
+            groupprop1:
+              type: 'string'");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var resultClass = codeModel.FindChildByName<CodeClass>("Group");
+        Assert.NotNull(resultClass);
+        Assert.Equal("directoryObject", resultClass.StartBlock.Inherits?.Name, StringComparer.OrdinalIgnoreCase);
+        Assert.Single(resultClass.Properties);
+        Assert.Single(resultClass.Properties.Where(static x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase)));
+    }
+    [Fact]
+    public async Task InheritanceWithAllOfWith1Part1SchemaAndPropertiesNoDiscriminator()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.1
+info:
+  title: OData Service for namespace microsoft.graph
+  description: This OData service is located at https://graph.microsoft.com/v1.0
+  version: 1.0.1
+servers:
+  - url: https://graph.microsoft.com/v1.0
+paths:
+  /group:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.group'
+components:
+  schemas:
+    microsoft.graph.directoryObject:
+      title: 'directoryObject'
+      required: ['@odata.type']
+      type: 'object'
+      properties:
+        '@odata.type':
+          type: 'string'
+          default: '#microsoft.graph.directoryObject'
+    microsoft.graph.group:
+      allOf:
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObject'
+      type: 'object'
+      properties:
+        groupprop1:
+          type: 'string'");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var resultClass = codeModel.FindChildByName<CodeClass>("Group");
+        Assert.NotNull(resultClass);
+        Assert.Equal("directoryObject", resultClass.StartBlock.Inherits?.Name, StringComparer.OrdinalIgnoreCase);
+        Assert.Single(resultClass.Properties);
+        Assert.Single(resultClass.Properties.Where(static x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase)));
+    }
+    [InlineData(true)]
+    [InlineData(false)]
+    [Theory]
+    public async Task InheritanceWithAllOfWith3Parts1Schema2Inline(bool reverseOrder)
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.1
+info:
+  title: OData Service for namespace microsoft.graph
+  description: This OData service is located at https://graph.microsoft.com/v1.0
+  version: 1.0.1
+servers:
+  - url: https://graph.microsoft.com/v1.0
+paths:
+  /directoryObject:
+    get:
+      responses: 
+        '200':
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/microsoft.graph.directoryObject'
+components:
+  schemas:
+    microsoft.graph.directoryObject:
+      required: ['@odata.type']
+      properties:
+        '@odata.type':
+          type: 'string'
+          default: '#microsoft.graph.directoryObject'
+      discriminator:
+        propertyName: '@odata.type'
+        mapping:
+          '#microsoft.graph.group': '#/components/schemas/microsoft.graph.group'
+    microsoft.graph.group:
+      allOf:"
+       + (reverseOrder ? "" : @" 
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObject'") + @"
+        - properties:
             groupprop1:
               type: 'string'
-        - title: 'group part 2'
-          type: 'object'
-          properties:
+        - properties:
             groupprop2:
-              type: 'string'");
+              type: 'string'" + (!reverseOrder ? "" : @" 
+        - '$ref': '#/components/schemas/microsoft.graph.directoryObject'"));
         var mockLogger = new Mock<ILogger<KiotaBuilder>>();
         var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
         var document = await builder.CreateOpenApiDocumentAsync(fs);
@@ -7451,9 +7792,60 @@ public async Task InheritanceWithAllOfWith3Parts()
         var codeModel = builder.CreateSourceModel(node);
         var resultClass = codeModel.FindChildByName<CodeClass>("Group");
         Assert.NotNull(resultClass);
+        Assert.Equal("directoryObject", resultClass.StartBlock.Inherits?.Name, StringComparer.OrdinalIgnoreCase);
         Assert.Equal(2, resultClass.Properties.Count());
-        Assert.Single(resultClass.Properties.Where(x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase)));
-        Assert.Single(resultClass.Properties.Where(x => x.Name.Equals("groupprop2", StringComparison.OrdinalIgnoreCase)));
+        Assert.Empty(resultClass.Properties.Where(static x => x.Name.Equals("oDataType", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(resultClass.Properties.Where(static x => x.Name.Equals("groupprop1", StringComparison.OrdinalIgnoreCase)));
+        Assert.Single(resultClass.Properties.Where(static x => x.Name.Equals("groupprop2", StringComparison.OrdinalIgnoreCase)));
+    }
+    [Fact]
+    public async Task InheritanceWithoutObjectTypeHasAllProperties()
+    {
+        var tempFilePath = Path.Combine(Path.GetTempPath(), Path.GetTempFileName());
+        await using var fs = await GetDocumentStream(@"openapi: 3.0.3
+servers:
+  - url: 'https://example.com'
+info:
+  title: example
+  version: 0.0.1
+paths:
+  /path:
+    post:
+      requestBody:
+        content:
+          application/json:
+            schema:
+              $ref: '#/components/schemas/outerPayload'
+      responses:
+        '201':
+          description: Created
+          content:
+            application/json:
+              schema:
+                type: string
+
+components:
+  schemas:
+    outerPayload:
+      allOf:
+        - $ref: '#/components/schemas/innerPayload'
+        - properties:
+            someField:
+              type: string
+    innerPayload:
+      properties:
+        anotherField:
+          type: string");
+        var mockLogger = new Mock<ILogger<KiotaBuilder>>();
+        var builder = new KiotaBuilder(mockLogger.Object, new GenerationConfiguration { ClientClassName = "Graph", OpenAPIFilePath = tempFilePath }, _httpClient);
+        var document = await builder.CreateOpenApiDocumentAsync(fs);
+        var node = builder.CreateUriSpace(document);
+        var codeModel = builder.CreateSourceModel(node);
+        var outerPayloadClass = codeModel.FindChildByName<CodeClass>("outerPayload");
+        Assert.NotNull(outerPayloadClass);
+        Assert.Equal("innerPayload", outerPayloadClass.StartBlock.Inherits?.Name, StringComparer.OrdinalIgnoreCase);
+        Assert.Single(outerPayloadClass.Properties);
+        Assert.Single(outerPayloadClass.Properties.Where(static x => x.Name.Equals("someField", StringComparison.OrdinalIgnoreCase)));
     }
     [Fact]
     public async Task EnumsWithNullableDoesNotResultInInlineType()