public static String getConstraintDefinitionFor(String isoLanguageCode, String id, Archetype a) {
   ArchetypeOntology ao = a.getOntology();
   List<OntologyDefinitions> odefs = ao.getConstraintDefinitionsList();
   Iterator it = odefs.iterator();
   while (it.hasNext()) {
     OntologyDefinitions od = (OntologyDefinitions) it.next();
     if (od.getLanguage().equals(isoLanguageCode)) {
       List<ArchetypeTerm> aterms = od.getDefinitions();
       Iterator it2 = aterms.iterator();
       while (it2.hasNext()) {
         ArchetypeTerm at = (ArchetypeTerm) it2.next();
         if (at.getCode().equals(id)) {
           return at.getItem("text");
         }
       }
     }
   }
   return "";
 }
 @Override
 public List<ArchetypeRelationship> extractArchetypeRelations(
     final Map<String, Archetype> archetypes,
     final Map<String, ArchetypeFile> archetypeFiles,
     final Map<String, FileProcessResult> results) {
   List<ArchetypeRelationship> relations = new ArrayList<ArchetypeRelationship>();
   final Map<String, OntologyDefinitions> termDefinitionMap =
       archetypes
           .entrySet()
           .stream()
           .map(
               entry -> {
                 Archetype archetype = entry.getValue();
                 OntologyDefinitions terms =
                     archetype
                         .getOntology()
                         .getTermDefinitionsList()
                         .stream()
                         .filter(
                             definition ->
                                 definition
                                     .getLanguage()
                                     .equals(archetype.getOriginalLanguage().getCodeString()))
                         .findFirst()
                         .get();
                 return new AbstractMap.SimpleEntry<String, OntologyDefinitions>(
                     archetype.getArchetypeId().getValue(), terms);
               })
           .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
   // Max iteration times = n*n
   termDefinitionMap.forEach(
       (archetypeName, termDefinitions) -> {
         termDefinitions
             .getDefinitions()
             .stream()
             .filter(
                 item ->
                     item.getItem(ArchetypeRelationship.RelationType.OneToMany.toString()) != null)
             .forEach(
                 item -> {
                   try {
                     String targetArchetypeName =
                         item.getItem(ArchetypeRelationship.RelationType.OneToMany.toString());
                     String mappedNodePath = item.getItem("mappedBy").replace("\"", "");
                     if (mappedNodePath == null) {
                       throw new ArchetypeRelationExtractException(
                           "Missing 'mappedBy' annotation.");
                     }
                     Archetype targetArchetype = archetypes.get(targetArchetypeName);
                     if (targetArchetype == null) {
                       throw new ArchetypeRelationExtractException(
                           "Missing archetype "
                               + targetArchetypeName
                               + " or OneToMany archetype name is wrong.");
                     }
                     String mappedNodeId = this.getNodeIdFromNodePath(mappedNodePath);
                     ArchetypeTerm targetTerm =
                         targetArchetype
                             .getOntology()
                             .termDefinition(
                                 targetArchetype.getOriginalLanguage().getCodeString(),
                                 mappedNodeId);
                     if (targetTerm == null) {
                       throw new ArchetypeRelationExtractException(
                           "'mappedBy' node path is wrong.");
                     }
                     String inverseArchetypeName =
                         targetTerm.getItem(
                             ArchetypeRelationship.RelationType.ManyToOne.toString());
                     if (inverseArchetypeName == null) {
                       throw new ArchetypeRelationExtractException(
                           "Archetype "
                               + targetArchetypeName
                               + "'s ontology term "
                               + targetTerm.getCode()
                               + " missing ManyToOne annotation.");
                     }
                     if (inverseArchetypeName.equals(archetypeName)) {
                       //												ArchetypeRelationship relation = new ArchetypeRelationship();
                       //												ArchetypeFile sourceArchetypeFile = archetypeFiles
                       //														.get(archetypeName);
                       //												ArchetypeFile definitionArchetypeFile = archetypeFiles
                       //														.get(targetArchetypeName);
                       //												relation.setSourceArchetypeFile(sourceArchetypeFile);
                       //												relation.setDestinationArchetypeFile(definitionArchetypeFile);
                       //												relation.setSourceArchetypeNode(sourceArchetypeFile
                       //														.getArchetypeNodeMap(
                       //																ArchetypeNode::getCode)
                       //														.get(item.getCode()));
                       //												relation.setDestinationArchetypeNode(definitionArchetypeFile
                       //														.getArchetypeNodeMap(
                       //																ArchetypeNode::getCode)
                       //														.get(targetTerm
                       //																.getCode()));
                       //												relations.add(relation);
                     } else {
                       this.logger.debug(
                           "OneToMany and ManyToOne relation does not match between {} and {}.",
                           archetypeName,
                           inverseArchetypeName);
                       throw new ArchetypeRelationExtractException(
                           "OneToMany and ManyToOne relation does not match between "
                               + archetypeName
                               + " and "
                               + archetypeName
                               + ".");
                     }
                   } catch (Exception ex) {
                     this.logger.debug("Extract archetype relation failed.", ex);
                     if (results != null) {
                       FileProcessResult result = results.get(archetypeName);
                       result.setStatus(FileProcessResult.FileStatusConstant.INVALID);
                       result.setMessage(
                           "Extract archetype relation failed, error: " + ex.getMessage());
                     }
                   }
                 });
         ;
       });
   return relations;
 }