docs: protected List<AbstractClassTypeDeclarationDescr> sortByHierarchy(Collection<AbstractClassTypeDeclarationDescr> unsortedDescrs, KnowledgeBuilderImpl kbuilder) {
  
          taxonomy = new HashMap<QualifiedName, Collection<QualifiedName>>();
          Map<QualifiedName, AbstractClassTypeDeclarationDescr> cache = new HashMap<QualifiedName, AbstractClassTypeDeclarationDescr>();
  
          for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
              cache.put(tdescr.getType(), tdescr);
          }
  
          for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
              QualifiedName name = tdescr.getType();
  
              Collection<QualifiedName> supers = taxonomy.get(name);
              if (supers == null) {
                  supers = new ArrayList<QualifiedName>();
                  taxonomy.put(name, supers);
              } else {
                  kbuilder.addBuilderResult(new TypeDeclarationError(tdescr,
                                                                     "Found duplicate declaration for type " + tdescr.getType()));
              }
  
              boolean circular = false;
              for (QualifiedName sup : tdescr.getSuperTypes()) {
                  if (!Object.class.getName().equals(name.getFullName())) {
                      if (!hasCircularDependency(tdescr.getType(), sup, taxonomy)) {
                          if (cache.containsKey(sup)) {
                              supers.add(sup);
                          }
                      } else {
                          circular = true;
                          kbuilder.addBuilderResult(new TypeDeclarationError(tdescr,
                                                                             "Found circular dependency for type " + tdescr.getTypeName()));
                          break;
                      }
                  }
              }
              if (circular) {
                  tdescr.getSuperTypes().clear();
              }
          }
  
          for (AbstractClassTypeDeclarationDescr tdescr : unsortedDescrs) {
              for (TypeFieldDescr field : tdescr.getFields().values()) {
                  QualifiedName name = tdescr.getType();
                  QualifiedName typeName = new QualifiedName(field.getPattern().getObjectType());
                  if (!hasCircularDependency(name, typeName, taxonomy)) {
                      if (cache.containsKey(typeName)) {
                          taxonomy.get(name).add(typeName);
                      }
                  } else {
                      field.setRecursive(true);
                  }
              }
          }
  
          List<QualifiedName> sorted = new HierarchySorter<QualifiedName>().sort(taxonomy);
          ArrayList list = new ArrayList(sorted.size());
          for (QualifiedName name : sorted) {
              list.add(cache.get(name));
          }
  
          return list;
      }