private SearchResult findInherited(EObject scopeDetermeningObject, QualifiedName fqn,
PPImportedNamesAdapter importedNames, List<QualifiedName> stack, SearchStrategy matchingStrategy,
EClass[] classes) {
// Protect against circular inheritance
QualifiedName containerName = fqn.skipLast(1);
if(stack.contains(containerName))
return new SearchResult();
stack.add(containerName);
// find using the given name
SearchResult searchResult = findExternal(scopeDetermeningObject, fqn, importedNames, matchingStrategy, classes);
final List<IEObjectDescription> result = searchResult.getAdjusted();
// Collect raw results to enable better error reporting on path errors
List<IEObjectDescription> rawResult = Lists.newArrayList();
rawResult.addAll(searchResult.getRaw());
// Search up the inheritance chain if no match (on exact match), or if a prefix search
if(result.isEmpty() || !matchingStrategy.isExists()) {
// find the parent type
if(containerName.getSegmentCount() > 0) {
// there was a parent
List<IEObjectDescription> parentResult = findExternal(
scopeDetermeningObject, containerName, importedNames, Match.EQUALS, DEF_AND_TYPE).getAdjusted();
if(!parentResult.isEmpty()) {
IEObjectDescription firstFound = parentResult.get(0);
String parentName = firstFound.getUserData(PPDSLConstants.PARENT_NAME_DATA);
if(parentName != null && parentName.length() > 0) {
// find attributes for parent
QualifiedName attributeFqn = converter.toQualifiedName(parentName);
attributeFqn = attributeFqn.append(fqn.getLastSegment());
SearchResult inheritedSearchResult = findInherited(
scopeDetermeningObject, attributeFqn, importedNames, stack, matchingStrategy, classes);
result.addAll(inheritedSearchResult.getAdjusted());
rawResult.addAll(inheritedSearchResult.getRaw());
}