private void addDescendants(SNode current, SNode node, Set<SNode> result) {
    if (SNodeUtil.isInstanceOfConceptDeclaration(current)) {
      for (SNode interfaceConcept : SNodeUtil.getConceptDeclaration_Implements(current)) {
        if (interfaceConcept != null && interfaceConcept == node) {
          result.add(current);
          break;
        }
      }
      if (SNodeUtil.getConceptDeclaration_Extends(current) == node) {
        result.add(current);
      }
    } else if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(current)) {
      for (SNode interfaceConcept : SNodeUtil.getInterfaceConceptDeclaration_Extends(current)) {
        if (interfaceConcept != null && interfaceConcept == node) {
          result.add(interfaceConcept);
          break;
        }
      }
    }

    for (SNode child : current.getChildren()) { // are there any "inner" concepts?
      addDescendants(child, node, result);
    }
  }
  private void collectAncestorNames(String conceptFqName, Set<String> result) {
    if (result.contains(conceptFqName)) return;

    result.add(conceptFqName);

    SNode declaration = SModelUtil.findConceptDeclaration(conceptFqName, GlobalScope.getInstance());
    if (declaration == null) {
      return;
    }

    if (SNodeUtil.isInstanceOfConceptDeclaration(declaration)) {
      SNode extendedConcept = SNodeUtil.getConceptDeclaration_Extends(declaration);
      if (extendedConcept != null) {
        Language declaringLanguage = SModelUtil.getDeclaringLanguage(extendedConcept);
        if (declaringLanguage != null) {
          collectAncestorNames(NameUtil.nodeFQName(extendedConcept), result);
        }
      } else if (!SNodeUtil.concept_BaseConcept.equals(NameUtil.nodeFQName(declaration))) {
        collectAncestorNames(SNodeUtil.concept_BaseConcept, result);
      }

      for (SNode interfaceConcept : SNodeUtil.getConceptDeclaration_Implements(declaration)) {
        if (interfaceConcept == null) continue;
        Language declaringLanguage = SModelUtil.getDeclaringLanguage(interfaceConcept);
        if (declaringLanguage == null) continue;
        collectAncestorNames(NameUtil.nodeFQName(interfaceConcept), result);
      }
    } else if (SNodeUtil.isInstanceOfInterfaceConceptDeclaration(declaration)) {
      for (SNode interfaceConcept : SNodeUtil.getInterfaceConceptDeclaration_Extends(declaration)) {
        if (interfaceConcept == null) continue;
        Language declaringLanguage = SModelUtil.getDeclaringLanguage(interfaceConcept);
        if (declaringLanguage == null) continue;
        collectAncestorNames(NameUtil.nodeFQName(interfaceConcept), result);
      }
    }
  }
    void build() {
      for (SNode cd : myLanguage.getConceptDeclarations()) {
        if (!(cd.getModel() != null && cd.getParent() == null)) continue;
        if (!SNodeUtil.isDefaultSubstitutable(cd)) {
          continue;
        }

        String fqName = NameUtil.nodeFQName(cd);

        for (String ancestor : getAncestorsNames_internal(fqName)) {
          Set<String> addTo = mySubconcepts.get(ancestor);
          if (addTo == null) {
            addTo = new HashSet<String>();
            mySubconcepts.put(ancestor, addTo);
          }
          addTo.add(fqName);
        }
      }
    }