private void ResolveForInterface( Declaration declaration, InheritanceModel result, Dictionary <DescriptionModel.TypeReference, HashSet <Declaration> > usages, Dictionary <Declaration, HashSet <Declaration> > rawInheritanceLists, Dictionary <Declaration, HashSet <Declaration> > rawInheritanceListsReversed, AstDescription astDescription) { if (settings.TypesRepresentedAsInterface.Contains(declaration.GetFullName())) { result.RepresentedAsInterface.Add(declaration); } var list = new HashSet <Declaration>(rawInheritanceLists[declaration]); bool shouldContinue = true; var item = new InheritanceModelDeclaration() { OriginalDeclaration = declaration }; while (shouldContinue) { shouldContinue = false; var entities = list.Where(i => !result.CollapsedToEmptyInterface.Contains(i) && !result.CollapsedToInterface.Contains(i)).ToArray(); var emptyInterfaces = list.Where(i => result.CollapsedToEmptyInterface.Contains(i)).ToArray(); var pureInterfaces = list.Where(i => result.CollapsedToInterface.Contains(i)).ToArray(); list.Clear(); if (emptyInterfaces.Length == 0 && pureInterfaces.Length == 0) { if (entities.Length <= 1) { if (entities.Length == 1) { item.BaseDeclaration = entities[0]; } } else { var filteredEntities = entities.Where(e => !entities.Any(e1 => e != e1 && this.FirstInheritsSecond(e1, e, rawInheritanceLists))).ToArray(); if (filteredEntities.Length < entities.Length) { shouldContinue = true; foreach (var e in filteredEntities) { list.Add(e); } } else { var collapsibleToEmpty = entities.Where(e => this.CanCollapseToEmptyInterface(e, rawInheritanceLists)).ToArray(); if (collapsibleToEmpty.Length > 0) { foreach (var e in collapsibleToEmpty) { this.CollapseToEmptyInterface(e, result, rawInheritanceLists); } shouldContinue = true; } else { var collapsible = entities .Where(e => this.CanCollapseToInterface(e, rawInheritanceLists)) .OrderBy(c => rawInheritanceListsReversed.ContainsKey(c) ? rawInheritanceListsReversed[c].Count : 0) .ToArray(); if (collapsible.Length > 0) { for (var i = 0; i < Math.Min(entities.Length - 1, collapsible.Length); i++) { this.CollapseToInterface(collapsible[i], result, rawInheritanceLists); } shouldContinue = true; } } foreach (var e in entities) { list.Add(e); } } if (!shouldContinue) { throw new InvalidOperationException("Unable to resolve inheritance list."); } } } else { foreach (var e in entities) { list.Add(e); } foreach (var empty in emptyInterfaces) { var baseItems = rawInheritanceLists[empty]; if (!item.ImplementedInterfaces.Any(i => this.FirstInheritsSecond(i, empty, rawInheritanceLists))) { item.ImplementedInterfaces.Add(empty); } foreach (var baseItem in baseItems) { list.Add(baseItem); } shouldContinue = true; } foreach (var pure in pureInterfaces) { var baseItems = rawInheritanceLists[pure]; if (!item.ImplementedInterfaces.Any(i => this.FirstInheritsSecond(i, pure, rawInheritanceLists))) { item.ImplementedInterfaces.Add(pure); item.MergedDeclarations.Add(pure); } foreach (var baseItem in baseItems) { list.Add(baseItem); } shouldContinue = true; } } } result.Declarations.Add(declaration.GetName(), item); }