cleanup
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / tcsxml / in / TcsXmlTaxonRelationsImport.java
index 0b52cf73b73eddf81901221e23cb46e64d91768b..7bb96b0ac685e86f8f5a2c1312e98e594aa743b6 100644 (file)
-/**\r
-* Copyright (C) 2009 EDIT\r
-* European Distributed Institute of Taxonomy\r
-* http://www.e-taxonomy.eu\r
-*\r
-* The contents of this file are subject to the Mozilla Public License Version 1.1\r
-* See LICENSE.TXT at the top of this package for the full license terms.\r
-*/\r
-\r
-package eu.etaxonomy.cdm.io.tcsxml.in;\r
-\r
-import java.io.InputStream;\r
-import java.util.ArrayList;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Map;\r
-import java.util.Set;\r
-\r
-import org.apache.log4j.Logger;\r
-import org.jdom.Element;\r
-import org.jdom.Namespace;\r
-import org.springframework.beans.factory.annotation.Autowired;\r
-import org.springframework.stereotype.Component;\r
-\r
-import eu.etaxonomy.cdm.common.CdmUtils;\r
-import eu.etaxonomy.cdm.common.ResultWrapper;\r
-import eu.etaxonomy.cdm.common.XmlHelp;\r
-import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;\r
-import eu.etaxonomy.cdm.io.common.ICdmIO;\r
-import eu.etaxonomy.cdm.io.common.MapWrapper;\r
-import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfImportConfigurator;\r
-import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfTaxonNameImport;\r
-import eu.etaxonomy.cdm.io.tcsxml.TcsXmlTransformer;\r
-import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.common.OriginalSourceType;\r
-import eu.etaxonomy.cdm.model.common.RelationshipTermBase;\r
-import eu.etaxonomy.cdm.model.description.CommonTaxonName;\r
-import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
-import eu.etaxonomy.cdm.model.name.TaxonName;\r
-import eu.etaxonomy.cdm.model.name.TaxonNameFactory;\r
-import eu.etaxonomy.cdm.model.reference.Reference;\r
-import eu.etaxonomy.cdm.model.taxon.Classification;\r
-import eu.etaxonomy.cdm.model.taxon.Synonym;\r
-import eu.etaxonomy.cdm.model.taxon.SynonymType;\r
-import eu.etaxonomy.cdm.model.taxon.Taxon;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
-import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
-import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;\r
-\r
-\r
-/**\r
- * @author a.mueller\r
- *\r
- */\r
-@Component\r
-public class TcsXmlTaxonRelationsImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {\r
-    private static final long serialVersionUID = 6632990505515905663L;\r
-\r
-    private static final Logger logger = Logger.getLogger(TcsXmlTaxonRelationsImport.class);\r
-\r
-       private static int modCount = 30000;\r
-\r
-       @Autowired\r
-       private TcsRdfTaxonNameImport rdfNameImport;\r
-       private TcsRdfImportConfigurator rdfConfig = TcsRdfImportConfigurator.NewInstance(null, null);\r
-\r
-       public TcsXmlTaxonRelationsImport(){\r
-               super();\r
-\r
-       }\r
-\r
-       @Override\r
-       public boolean doCheck(TcsXmlImportState state){\r
-               boolean result = true;\r
-               logger.warn("Checking for TaxonRelations not yet implemented");\r
-               logger.warn("Creation of homotypic relations is still problematic");\r
-               //result &= checkArticlesWithoutJournal(bmiConfig);\r
-               //result &= checkPartOfJournal(bmiConfig);\r
-\r
-               return result;\r
-       }\r
-\r
-       @Override\r
-       public void doInvoke(TcsXmlImportState state){\r
-\r
-\r
-               logger.info("start make taxon relations ...");\r
-               MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);\r
-               MapWrapper<TaxonName> taxonNameMap = (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE);\r
-               MapWrapper<Reference> referenceMap = (MapWrapper<Reference>)state.getStore(ICdmIO.REFERENCE_STORE);\r
-\r
-               Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();\r
-\r
-               ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);\r
-               String childName;\r
-               boolean obligatory;\r
-               String idNamespace = "TaxonRelation";\r
-\r
-               TcsXmlImportConfigurator config = state.getConfig();\r
-               Element elDataSet = super.getDataSetElement(config);\r
-               Namespace tcsNamespace = config.getTcsXmlNamespace();\r
-\r
-               childName = "TaxonConcepts";\r
-               obligatory = false;\r
-               Element elTaxonConcepts = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);\r
-\r
-               childName = "TaxonConcept";\r
-               List<Element> elTaxonConceptList =  elTaxonConcepts == null ? new ArrayList<Element>() : elTaxonConcepts.getChildren(childName, tcsNamespace);\r
-\r
-               int i = 0;\r
-               int taxonRelCount = 0;\r
-\r
-               //for each taxonConcept\r
-               logger.info("NUmber of taxon concepts: " + elTaxonConceptList.size());\r
-               for (Element elTaxonConcept : elTaxonConceptList){\r
-                       if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}\r
-                       taxonRelCount += makeTaxonConcept(state, taxonMap, taxonStore, elTaxonConcept, tcsNamespace, success);\r
-               }//elTaxonConcept\r
-               logger.info("Taxa handled: " + taxonStore.size());\r
-               //TaxonRelationshipAssertions\r
-               taxonRelCount += makeTaxonRelationshipAssertion(state, taxonMap, referenceMap, taxonStore, elDataSet, tcsNamespace, success);\r
-\r
-               logger.info("Taxa to save: " + taxonStore.size());\r
-               getTaxonService().save(taxonStore);\r
-\r
-               //do basionym relationships\r
-               childName = "TaxonNames";\r
-               obligatory = false;\r
-               Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);\r
-\r
-               childName = "TaxonName";\r
-               List<Element> elTaxonNameList =  elTaxonNames == null ? new ArrayList<Element>() : elTaxonNames.getChildren(childName, tcsNamespace);\r
-\r
-               logger.info("NUmber of taxon concepts: " + elTaxonNameList.size());\r
-               for (Element elTaxonName : elTaxonNameList){\r
-                       if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}\r
-                       taxonRelCount += makeBasionymRelations(state, taxonMap, taxonNameMap, taxonStore, elTaxonName, tcsNamespace, success);\r
-               }//elTaxonConcept\r
-               logger.info("Taxa handled: " + taxonStore.size());\r
-\r
-\r
-               taxonStore = null;\r
-               logger.info("end make taxon relations ...");\r
-               if (!success.getValue()){\r
-                       state.setUnsuccessfull();\r
-               }\r
-               return;\r
-       }\r
-\r
-       private int makeBasionymRelations(TcsXmlImportState state,\r
-                       MapWrapper<TaxonBase> taxonMap, MapWrapper<TaxonName> taxonNameMap, Set<TaxonBase> taxonStore,\r
-                       Element elTaxonName, Namespace tcsNamespace,\r
-                       ResultWrapper<Boolean> success) {\r
-\r
-               /*\r
-                * <tcs:Basionym>\r
-                               <tcs:RelatedName ref="urn:lsid:ipni.org:names:50000063-1">Caryophyllaceae</tcs:RelatedName>\r
-                       </tcs:Basionym>\r
-                */\r
-\r
-\r
-               String childName = "Basionym";\r
-               boolean obligatory = false;\r
-               Element elBasionymRelationships = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);\r
-               if (elBasionymRelationships != null){\r
-                       childName = "RelatedName";\r
-                       obligatory = false;\r
-                       Element elBasionym = XmlHelp.getSingleChildElement(success, elBasionymRelationships, childName, tcsNamespace, obligatory);\r
-\r
-                       String id = elTaxonName.getAttributeValue("id");\r
-                       TaxonName name = taxonNameMap.get(removeVersionOfRef(id));\r
-\r
-                       TaxonBase taxonBase = (TaxonBase)name.getTaxonBases().iterator().next();\r
-\r
-                       String ref = elBasionym.getAttributeValue("ref");\r
-                       TaxonName basionymName = taxonNameMap.get(removeVersionOfRef(ref));\r
-\r
-                       if (basionymName != null){\r
-                               basionymName = HibernateProxyHelper.deproxy(basionymName, TaxonName.class);\r
-                               TaxonBase basionym;\r
-                               if (basionymName.getTaxonBases().isEmpty()){\r
-                                        basionym = Synonym.NewInstance(basionymName, null);\r
-                               }else{\r
-                                       basionym = (TaxonBase)basionymName.getTaxonBases().iterator().next();\r
-                               }\r
-                               //Synonym basionymSyn;\r
-                               if (basionym instanceof Taxon){\r
-\r
-                                       if (!(taxonBase instanceof Synonym)){\r
-                                               logger.debug("The taxon " + basionymName.getTitleCache() + " is used in a concept and can not be a synonym " + name.getTitleCache() + "but will be added as basionym for the homotypical group");\r
-                                               name.addBasionym(basionymName);\r
-                                               //basionymName.getHomotypicalGroup().addTypifiedName(name);\r
-                                       } else if (taxonBase instanceof Synonym){\r
-                                               Synonym synonym = (Synonym) taxonBase;\r
-                                               ((Taxon)basionym).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());\r
-                                               basionym.getHomotypicGroup().setGroupBasionym(basionymName);\r
-                                               taxonStore.add(basionym);\r
-                                       }\r
-                               }else{\r
-                                       if (taxonBase instanceof Taxon){\r
-                                               Synonym synonym = (Synonym) basionym;\r
-                                               ((Taxon)taxonBase).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF());\r
-                                               taxonBase.getHomotypicGroup().setGroupBasionym(basionymName);\r
-                                               taxonStore.add(taxonBase);\r
-                                       } else{\r
-                                           Taxon acc = ((Synonym)taxonBase).getAcceptedTaxon();\r
-                                               if (acc != null){\r
-                                                       acc.addHomotypicSynonym((Synonym)basionym);\r
-                                                       basionymName.getHomotypicalGroup().setGroupBasionym(basionymName);\r
-                                               }\r
-                                       }\r
-                               }\r
-\r
-\r
-                       } else{\r
-                               basionymName = TaxonNameFactory.NewNonViralInstance(name.getRank());\r
-                               childName = "RelatedName";\r
-                               obligatory = true;\r
-                               Element elName = XmlHelp.getSingleChildElement(success, elBasionym, childName, tcsNamespace, obligatory);\r
-                               String strName = (elName == null)? "" : elName.getTextNormalize();\r
-                               basionymName.setTitleCache(strName, false);\r
-                               Synonym basionymSyn = Synonym.NewInstance(basionymName, unknownSec());\r
-                               if (taxonBase instanceof Taxon){\r
-                                       Taxon taxon = (Taxon)taxonBase;\r
-                                       taxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());\r
-                                       taxon.getHomotypicGroup().setGroupBasionym(basionymName);\r
-                                       taxonStore.add(taxon);\r
-                               } else{\r
-                                       Synonym syn = (Synonym) taxonBase;\r
-                                       if (syn.getAcceptedTaxon() != null){\r
-                                               Taxon accTaxon = syn.getAcceptedTaxon();\r
-                                               accTaxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF());\r
-                                               accTaxon.getHomotypicGroup().setGroupBasionym(basionymName);\r
-                                               taxonStore.add(accTaxon);\r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               return 1;\r
-       }\r
-\r
-       private int makeTaxonConcept(TcsXmlImportState state, MapWrapper<TaxonBase> taxonMap, Set<TaxonBase> taxonStore, Element elTaxonConcept, Namespace tcsNamespace, ResultWrapper<Boolean> success){\r
-               int taxonRelCount = 0;\r
-\r
-               String childName = "TaxonRelationships";\r
-               boolean obligatory = false;\r
-               Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);\r
-\r
-               if (elTaxonRelationships != null){\r
-                       //Relationships\r
-                       String tcsElementName = "TaxonRelationship";\r
-                       List<Element> elTaxonRelationshipList = elTaxonRelationships.getChildren(tcsElementName, tcsNamespace);\r
-                       logger.info("Number of taxonrelationships: " + elTaxonRelationshipList.size());\r
-                       for (Element elTaxonRelationship: elTaxonRelationshipList){\r
-\r
-                               taxonRelCount++;\r
-                               logger.debug("TaxonRelationship "+  taxonRelCount);\r
-\r
-                               String strId = elTaxonConcept.getAttributeValue("id");\r
-                               //TODO\r
-//                             String strConceptType = elTaxonConcept.getAttributeValue("type"); //original, revision, incomplete, aggregate, nominal\r
-//                             String strPrimary = elTaxonConcept.getAttributeValue("primary"); //If primary='true' the concept is the first level response to a query. If 'false' the concept may be a secondary concept linked directly or indirectly to the definition of a primary concept.\r
-//                             String strForm = elTaxonConcept.getAttributeValue("form");  //anamorph, teleomorph, hybrid\r
-\r
-                               TaxonBase fromTaxon = taxonMap.get(removeVersionOfRef(strId));\r
-                               makeRelationshipType(state, elTaxonRelationship, taxonMap, taxonStore, fromTaxon, success);\r
-\r
-                               if (fromTaxon instanceof Taxon){\r
-                                       makeHomotypicSynonymRelations((Taxon)fromTaxon);\r
-                               }\r
-                       }// end Relationship\r
-               }\r
-               return taxonRelCount;\r
-       }\r
-\r
-       private int makeTaxonRelationshipAssertion(\r
-                       TcsXmlImportState state,\r
-                       MapWrapper<TaxonBase> taxonMap,\r
-                       MapWrapper<Reference> referenceMap,\r
-                       Set<TaxonBase> taxonStore,\r
-                       Element elDataSet,\r
-                       Namespace tcsNamespace,\r
-                       ResultWrapper<Boolean> success){\r
-\r
-               int i = 0;\r
-               String childName = "TaxonRelationshipAssertions";\r
-               boolean obligatory = false;\r
-               Element elTaxonRelationshipAssertions = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);\r
-               if(elTaxonRelationshipAssertions == null){\r
-                       return 0;\r
-               }\r
-\r
-               childName = "TaxonRelationshipAssertion";\r
-               List<Element> elTaxonRelationshipAssertionList = elTaxonRelationshipAssertions.getChildren(childName, tcsNamespace);\r
-               //for each taxon relationship assertion\r
-               for (Element elTaxonRelationshipAssertion : elTaxonRelationshipAssertionList){\r
-                       if ((i++ % modCount) == 0){ logger.info("TaxonRelationshipAssertions handled: " + (i-1));}\r
-                       String strId = elTaxonRelationshipAssertion.getAttributeValue("id");\r
-                       //TODO id\r
-\r
-                       childName = "AccordingTo";\r
-                       obligatory = true;\r
-                       Element elAccordingTo = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);\r
-                       Reference ref = makeAccordingTo(elAccordingTo, referenceMap, success);\r
-\r
-                       childName = "FromTaxonConcept";\r
-                       obligatory = true;\r
-                       Element elFromTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);\r
-\r
-                       Class<? extends TaxonBase> clazz = Taxon.class;\r
-                       //TODO if synonym\r
-                       TaxonBase fromTaxon = makeReferenceType(elFromTaxonConcept, clazz, taxonMap, success);\r
-\r
-                       makeRelationshipType(state, elTaxonRelationshipAssertion, taxonMap, taxonStore, fromTaxon, success);\r
-               }//elTaxonRelationshipAssertion\r
-\r
-               return i;\r
-       }\r
-\r
-\r
-       /**\r
-        * Handles the TCS RelationshipType element.\r
-        * @param tcsConfig\r
-        * @param elRelationship\r
-        * @param taxonMap\r
-        * @param taxonStore\r
-        * @param fromTaxon\r
-        * @param success\r
-        */\r
-       private void makeRelationshipType(\r
-                       TcsXmlImportState state\r
-                       , Element elRelationship\r
-                       , MapWrapper<TaxonBase> taxonMap\r
-                       , Set<TaxonBase> taxonStore\r
-                       , TaxonBase fromTaxon\r
-                       , ResultWrapper<Boolean> success\r
-                       ){\r
-\r
-               if (elRelationship == null){\r
-                       success.setValue(false);\r
-               }\r
-               String strRelType = elRelationship.getAttributeValue("type");\r
-\r
-\r
-               try {\r
-                       ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();\r
-                       isInverse.setValue(false);\r
-                       if ("has vernacular".equalsIgnoreCase(strRelType)){\r
-                               handleVernacular(success, state, elRelationship, fromTaxon);\r
-                       }else{\r
-                               RelationshipTermBase<?> relType = TcsXmlTransformer.tcsRelationshipType2Relationship(strRelType, isInverse);\r
-\r
-                               //toTaxon (should be part of relationshipType)\r
-                               boolean isSynonym = (relType instanceof SynonymType);\r
-                               TaxonBase toTaxon = getToTaxon(elRelationship, taxonMap, state.getMissingConceptLSIDs(), isSynonym, success, state);\r
-\r
-                               if (toTaxon != null && fromTaxon != null){\r
-                                       //exchange taxa if relationship is inverse\r
-                                       if (isInverse.getValue() == true ){\r
-                                               TaxonBase tmp = toTaxon;\r
-                                               toTaxon = fromTaxon;\r
-                                               fromTaxon = tmp;\r
-                                       }\r
-\r
-                                       //Create relationship\r
-                                       if (! (toTaxon instanceof Taxon)){\r
-                                               logger.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");\r
-                                               success.setValue(false);\r
-                                       }else{\r
-                                               Taxon taxonTo = (Taxon)toTaxon;\r
-                                               if (relType instanceof SynonymType){\r
-                                                       SynonymType synRelType = (SynonymType)relType;\r
-                                                       if (! (fromTaxon instanceof Synonym )){\r
-                                                               logger.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");\r
-                                                               success.setValue(false);\r
-                                                       }else{\r
-                                                               Synonym synonym = (Synonym)fromTaxon;\r
-                                                               TaxonName synName = synonym.getName();\r
-                                                               TaxonName accName = taxonTo.getName();\r
-                                                               if (synName != null && accName != null && synName.isHomotypic(accName)\r
-                                                                                       && ( synRelType.equals(SynonymType.SYNONYM_OF()))){\r
-                                                                       synRelType = SynonymType.HOMOTYPIC_SYNONYM_OF();\r
-                                                               }\r
-                                                               if (! relationExists(taxonTo, synonym, synRelType)){\r
-                                                                       taxonTo.addSynonym(synonym, synRelType);\r
-                                                               }else{\r
-                                                                       //TODO citation, microReference\r
-                                                                       //TODO different synRelTypes -> warning\r
-                                                                       success.setValue(false);\r
-                                                               }\r
-                                                       }\r
-                                               }else if (relType instanceof TaxonRelationshipType){\r
-                                                       Reference citation = null;\r
-                                                       String microReference = null;\r
-                                                   makeTaxonRelationship(state, (TaxonRelationshipType)relType, fromTaxon, taxonTo, citation, microReference, success);\r
-                                               }else{\r
-                                                       logger.warn("Unknown Relationshiptype");\r
-                                                       success.setValue(false);\r
-                                               }\r
-                                               taxonStore.add(toTaxon);\r
-                                       }\r
-                               }else{\r
-                                       if (toTaxon == null){\r
-                                       //      logger.warn("toTaxon (" + /*strToTaxon + */ ") could  not be found in taxonMap. Relationship of type " + strRelType + " was not added to CDM");\r
-                                       }\r
-                                       if (fromTaxon == null){\r
-                                       //      logger.warn("fromTaxon (" + /*strTaxonAbout + */") could not be found in taxonMap. Relationship was not added to CDM");\r
-                                       }\r
-                                       success.setValue(false);\r
-                               }\r
-                       }\r
-               } catch (UnknownCdmTypeException e) {\r
-                       //TODO\r
-                       logger.warn("relationshipType " + strRelType + " not yet implemented");\r
-                       success.setValue(false);\r
-               }\r
-               return;\r
-       }\r
-\r
-       private void handleVernacular(ResultWrapper<Boolean> success, TcsXmlImportState state, Element elRelationship, TaxonBase taxonBase) {\r
-               if (! taxonBase.isInstanceOf(Taxon.class)){\r
-                       logger.warn("From Taxon is not of type Taxon but of type " +  taxonBase.getClass().getSimpleName());\r
-                       success.setValue(false);\r
-                       return;\r
-               }else{\r
-                       Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);\r
-                       Map<String, CommonTaxonName> commonNameMap = state.getCommonNameMap();\r
-                       CommonTaxonName commonTaxonName = getCommonName(elRelationship, commonNameMap, success);\r
-                       TaxonDescription description = getDescription(taxon);\r
-                       description.addElement(commonTaxonName);\r
-               }\r
-       }\r
-\r
-       private TaxonDescription getDescription(Taxon taxon) {\r
-               if (taxon.getDescriptions().isEmpty()){\r
-                       return TaxonDescription.NewInstance(taxon);\r
-               }else{\r
-                       //TODO only if the description represents this TCS file\r
-                       return taxon.getDescriptions().iterator().next();\r
-               }\r
-       }\r
-\r
-       private CommonTaxonName getCommonName(Element elTaxonRelationship, Map<String, CommonTaxonName> commonNameMap, ResultWrapper<Boolean> success){\r
-               CommonTaxonName result = null;\r
-               if (elTaxonRelationship == null || commonNameMap == null){\r
-                       success.setValue(false);\r
-               }else{\r
-                       String childName = "ToTaxonConcept";\r
-                       boolean obligatory = true;\r
-                       Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);\r
-\r
-                       String linkType = elToTaxonConcept.getAttributeValue("linkType");\r
-                       if (linkType == null || linkType.equals("local")){\r
-                               String ref = elToTaxonConcept.getAttributeValue("ref");\r
-                               if (ref != null){\r
-                                       result = commonNameMap.get(ref);\r
-                               }else{\r
-                                       logger.warn("Non ref not yet implemented for vernacular name relationship");\r
-                               }\r
-                       }else{\r
-                               logger.warn("External link types for vernacular name not yet implemented");\r
-                       }\r
-               }\r
-               return result;\r
-       }\r
-\r
-       private void makeTaxonRelationship(TcsXmlImportState state, TaxonRelationshipType relType, TaxonBase fromTaxon, Taxon taxonTo, Reference citation, String microReference, ResultWrapper<Boolean> success){\r
-               TaxonRelationshipType taxRelType = relType;\r
-               if (! (fromTaxon instanceof Taxon )){\r
-                       logger.warn("TaxonBase fromTaxon " + /*strTaxonAbout +*/ "is not of Type 'Taxon'. Relationship is not added.");\r
-                       success.setValue(false);\r
-               }else{\r
-                       Taxon taxonFrom = (Taxon)fromTaxon;\r
-                       if (relType.equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){\r
-                               makeTaxonomicallyIncluded(state, taxonTo, taxonFrom, citation, microReference);\r
-                       }else{\r
-                               taxonFrom.addTaxonRelation(taxonTo, taxRelType, citation, microReference);\r
-                       }\r
-               }\r
-       }\r
-\r
-       private boolean makeTaxonomicallyIncluded(TcsXmlImportState state, Taxon toTaxon, Taxon fromTaxon, Reference citation, String microCitation){\r
-               Reference sec = toTaxon.getSec();\r
-               Classification tree = state.getTree(sec);\r
-               if (tree == null){\r
-                       tree = makeTree(state, sec);\r
-               }\r
-               TaxonNode childNode = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);\r
-               return (childNode != null);\r
-       }\r
-\r
-\r
-       @SuppressWarnings("rawtypes")\r
-       private TaxonBase getToTaxon(Element elTaxonRelationship, MapWrapper<TaxonBase> map, List<String> missingNameID,boolean isSynonym, ResultWrapper<Boolean> success, TcsXmlImportState state){\r
-               TaxonBase result = null;\r
-               if (elTaxonRelationship == null || map == null){\r
-                       success.setValue(false);\r
-               }else{\r
-                       String childName = "ToTaxonConcept";\r
-                       boolean obligatory = true;\r
-                       Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);\r
-\r
-\r
-                       String linkType = elToTaxonConcept.getAttributeValue("linkType");\r
-                       if (linkType == null || linkType.equals("local")){\r
-                               String ref = elToTaxonConcept.getAttributeValue("ref");\r
-                               if (ref != null){\r
-                                       result = map.get(ref);\r
-                                       if (result == null && state.getConfig().isDoGetMissingNames()){\r
-\r
-\r
-                                               String[] split= ref.split(":");\r
-                                               String id = split[split.length-1];\r
-                                               logger.info("get name for id " + id);\r
-                                               if (missingNameID.contains(id)){\r
-                                                   return null;\r
-                                               }\r
-                                               InputStream nameStream = service.getNamesById(id);\r
-\r
-\r
-                                               try{\r
-                                                       String nameUri = "urn:lsid:ipni.org:names:"+ id;\r
-                                                       TaxonName name = rdfNameImport.handleRdfElementFromStream(nameStream, rdfConfig, (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE), nameUri);\r
-                                                       if (name != null){\r
-                                                               if (name.getTaxa().isEmpty()){\r
-\r
-                                                                       result = Taxon.NewInstance(name, null);\r
-                                                               }else{\r
-                                                                       result = (TaxonBase)name.getTaxa().iterator().next();\r
-                                                               }\r
-                                                               name.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);\r
-                                                               result.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);\r
-\r
-                                                               map.put(removeVersionOfRef(ref), result);\r
-                                                       } else{\r
-                                                           missingNameID.add(id);\r
-                                                       }\r
-                                               }catch(Exception e){\r
-                                                       logger.debug(e.getMessage());\r
-                                                       e.printStackTrace();\r
-                                               }\r
-                                       }\r
-                               }else{\r
-                                       String title = elToTaxonConcept.getTextNormalize();\r
-                                       //TODO synonym?\r
-                                       TaxonName taxonName = TaxonNameFactory.NewNonViralInstance(null);\r
-                                       taxonName.setTitleCache(title, true);\r
-                                       logger.warn("Free text related taxon seems to be bug in TCS");\r
-                                       if (isSynonym){\r
-                                               result = Synonym.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());\r
-                                       }else{\r
-                                               result = Taxon.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());\r
-                                       }\r
-                                       result.setTitleCache(title, true);\r
-                               }\r
-                       }else{\r
-                               logger.warn("External link types for synonym not yet implemented");\r
-                       }\r
-               }\r
-               return result;\r
-       }\r
-\r
-       private boolean relationExists(Taxon taxonTo, Synonym synonym, SynonymType synRelType){\r
-               if (synonym == null || taxonTo == null\r
-                       || !taxonTo.equals(synonym.getAcceptedTaxon())){\r
-                       return false;\r
-               }else{\r
-                   return CdmUtils.nullSafeEqual(synonym.getType(),synRelType);\r
-               }\r
-       }\r
-\r
-       private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon){\r
-               TaxonName aboutName = aboutTaxon.getName();\r
-               if (aboutName != null){\r
-                       Set<TaxonName> typifiedNames = aboutName.getHomotypicalGroup().getTypifiedNames();\r
-                       for (TaxonName<?,?> typifiedName : typifiedNames){\r
-                               //TODO check if name is part of this tcs file\r
-                               if (typifiedName.equals(aboutName)){\r
-                                       continue;\r
-                               }\r
-                               Set<Synonym> syns = typifiedName.getSynonyms();\r
-                               for(Synonym syn:syns){\r
-                                       aboutTaxon.addSynonym(syn, SynonymType.HOMOTYPIC_SYNONYM_OF());\r
-                               }\r
-                       }\r
-               }\r
-               return true;\r
-       }\r
-\r
-       @Override\r
-    protected boolean isIgnore(TcsXmlImportState state){\r
-               return ! state.getConfig().isDoRelTaxa();\r
-       }\r
-}\r
+/**
+* Copyright (C) 2009 EDIT
+* European Distributed Institute of Taxonomy
+* http://www.e-taxonomy.eu
+*
+* The contents of this file are subject to the Mozilla Public License Version 1.1
+* See LICENSE.TXT at the top of this package for the full license terms.
+*/
+
+package eu.etaxonomy.cdm.io.tcsxml.in;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.jdom.Element;
+import org.jdom.Namespace;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import eu.etaxonomy.cdm.common.CdmUtils;
+import eu.etaxonomy.cdm.common.ResultWrapper;
+import eu.etaxonomy.cdm.common.XmlHelp;
+import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
+import eu.etaxonomy.cdm.io.common.ICdmIO;
+import eu.etaxonomy.cdm.io.common.MapWrapper;
+import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfImportConfigurator;
+import eu.etaxonomy.cdm.io.tcsrdf.TcsRdfTaxonNameImport;
+import eu.etaxonomy.cdm.io.tcsxml.TcsXmlTransformer;
+import eu.etaxonomy.cdm.model.common.CdmBase;
+import eu.etaxonomy.cdm.model.common.IRelationshipType;
+import eu.etaxonomy.cdm.model.description.CommonTaxonName;
+import eu.etaxonomy.cdm.model.description.TaxonDescription;
+import eu.etaxonomy.cdm.model.name.TaxonName;
+import eu.etaxonomy.cdm.model.name.TaxonNameFactory;
+import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
+import eu.etaxonomy.cdm.model.reference.Reference;
+import eu.etaxonomy.cdm.model.taxon.Classification;
+import eu.etaxonomy.cdm.model.taxon.Synonym;
+import eu.etaxonomy.cdm.model.taxon.SynonymType;
+import eu.etaxonomy.cdm.model.taxon.Taxon;
+import eu.etaxonomy.cdm.model.taxon.TaxonBase;
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;
+import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;
+import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;
+
+
+/**
+ * @author a.mueller
+ *
+ */
+@Component
+public class TcsXmlTaxonRelationsImport extends TcsXmlImportBase implements ICdmIO<TcsXmlImportState> {
+    private static final long serialVersionUID = 6632990505515905663L;
+
+    private static final Logger logger = LogManager.getLogger(TcsXmlTaxonRelationsImport.class);
+
+       private static int modCount = 30000;
+
+       @Autowired
+       private TcsRdfTaxonNameImport rdfNameImport;
+       private TcsRdfImportConfigurator rdfConfig = TcsRdfImportConfigurator.NewInstance(null, null);
+
+       public TcsXmlTaxonRelationsImport(){
+               super();
+
+       }
+
+       @Override
+       public boolean doCheck(TcsXmlImportState state){
+               boolean result = true;
+               logger.warn("Checking for TaxonRelations not yet implemented");
+               logger.warn("Creation of homotypic relations is still problematic");
+               //result &= checkArticlesWithoutJournal(bmiConfig);
+               //result &= checkPartOfJournal(bmiConfig);
+
+               return result;
+       }
+
+       @Override
+       public void doInvoke(TcsXmlImportState state){
+
+
+               logger.info("start make taxon relations ...");
+               MapWrapper<TaxonBase> taxonMap = (MapWrapper<TaxonBase>)state.getStore(ICdmIO.TAXON_STORE);
+               MapWrapper<TaxonName> taxonNameMap = (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE);
+               MapWrapper<Reference> referenceMap = (MapWrapper<Reference>)state.getStore(ICdmIO.REFERENCE_STORE);
+
+               Set<TaxonBase> taxonStore = new HashSet<TaxonBase>();
+
+               ResultWrapper<Boolean> success = ResultWrapper.NewInstance(true);
+               String childName;
+               boolean obligatory;
+               String idNamespace = "TaxonRelationDTO";
+
+               TcsXmlImportConfigurator config = state.getConfig();
+               Element elDataSet = super.getDataSetElement(config);
+               Namespace tcsNamespace = config.getTcsXmlNamespace();
+
+               childName = "TaxonConcepts";
+               obligatory = false;
+               Element elTaxonConcepts = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
+
+               childName = "TaxonConcept";
+               List<Element> elTaxonConceptList =  elTaxonConcepts == null ? new ArrayList<Element>() : elTaxonConcepts.getChildren(childName, tcsNamespace);
+
+               int i = 0;
+               int taxonRelCount = 0;
+
+               //for each taxonConcept
+               logger.info("NUmber of taxon concepts: " + elTaxonConceptList.size());
+               for (Element elTaxonConcept : elTaxonConceptList){
+                       if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
+                       taxonRelCount += makeTaxonConcept(state, taxonMap, taxonStore, elTaxonConcept, tcsNamespace, success);
+               }//elTaxonConcept
+               logger.info("Taxa handled: " + taxonStore.size());
+               //TaxonRelationshipAssertions
+               taxonRelCount += makeTaxonRelationshipAssertion(state, taxonMap, referenceMap, taxonStore, elDataSet, tcsNamespace, success);
+
+               logger.info("Taxa to save: " + taxonStore.size());
+               getTaxonService().save(taxonStore);
+
+               //do basionym relationships
+               childName = "TaxonNames";
+               obligatory = false;
+               Element elTaxonNames = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
+
+               childName = "TaxonName";
+               List<Element> elTaxonNameList =  elTaxonNames == null ? new ArrayList<Element>() : elTaxonNames.getChildren(childName, tcsNamespace);
+
+               logger.info("NUmber of taxon concepts: " + elTaxonNameList.size());
+               for (Element elTaxonName : elTaxonNameList){
+                       if ((i++ % modCount) == 0){ logger.info("Taxa handled: " + (i-1));}
+                       taxonRelCount += makeBasionymRelations(state, taxonMap, taxonNameMap, taxonStore, elTaxonName, tcsNamespace, success);
+               }//elTaxonConcept
+               logger.info("Taxa handled: " + taxonStore.size());
+
+
+               taxonStore = null;
+               logger.info("end make taxon relations ...");
+               if (!success.getValue()){
+                       state.setUnsuccessfull();
+               }
+               return;
+       }
+
+       private int makeBasionymRelations(TcsXmlImportState state,
+                       MapWrapper<TaxonBase> taxonMap, MapWrapper<TaxonName> taxonNameMap, Set<TaxonBase> taxonStore,
+                       Element elTaxonName, Namespace tcsNamespace,
+                       ResultWrapper<Boolean> success) {
+
+               /*
+                * <tcs:Basionym>
+                               <tcs:RelatedName ref="urn:lsid:ipni.org:names:50000063-1">Caryophyllaceae</tcs:RelatedName>
+                       </tcs:Basionym>
+                */
+
+
+               String childName = "Basionym";
+               boolean obligatory = false;
+               Element elBasionymRelationships = XmlHelp.getSingleChildElement(success, elTaxonName, childName, tcsNamespace, obligatory);
+               if (elBasionymRelationships != null){
+                       childName = "RelatedName";
+                       obligatory = false;
+                       Element elBasionym = XmlHelp.getSingleChildElement(success, elBasionymRelationships, childName, tcsNamespace, obligatory);
+
+                       String id = elTaxonName.getAttributeValue("id");
+                       TaxonName name = taxonNameMap.get(removeVersionOfRef(id));
+
+                       TaxonBase taxonBase = name.getTaxonBases().iterator().next();
+
+                       String ref = elBasionym.getAttributeValue("ref");
+                       TaxonName basionymName = taxonNameMap.get(removeVersionOfRef(ref));
+
+                       if (basionymName != null){
+                               basionymName = HibernateProxyHelper.deproxy(basionymName, TaxonName.class);
+                               TaxonBase basionym;
+                               if (basionymName.getTaxonBases().isEmpty()){
+                                        basionym = Synonym.NewInstance(basionymName, null);
+                               }else{
+                                       basionym = basionymName.getTaxonBases().iterator().next();
+                               }
+                               //Synonym basionymSyn;
+                               if (basionym instanceof Taxon){
+
+                                       if (!(taxonBase instanceof Synonym)){
+                                               logger.debug("The taxon " + basionymName.getTitleCache() + " is used in a concept and can not be a synonym " + name.getTitleCache() + "but will be added as basionym for the homotypical group");
+                                               name.addBasionym(basionymName);
+                                               //basionymName.getHomotypicalGroup().addTypifiedName(name);
+                                       } else if (taxonBase instanceof Synonym){
+                                               Synonym synonym = (Synonym) taxonBase;
+                                               ((Taxon)basionym).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF);
+                                               basionym.getHomotypicGroup().setGroupBasionym(basionymName);
+                                               taxonStore.add(basionym);
+                                       }
+                               }else{
+                                       if (taxonBase instanceof Taxon){
+                                               Synonym synonym = (Synonym) basionym;
+                                               ((Taxon)taxonBase).addSynonym(synonym, SynonymType.HOMOTYPIC_SYNONYM_OF);
+                                               taxonBase.getHomotypicGroup().setGroupBasionym(basionymName);
+                                               taxonStore.add(taxonBase);
+                                       } else{
+                                           Taxon acc = ((Synonym)taxonBase).getAcceptedTaxon();
+                                               if (acc != null){
+                                                       acc.addHomotypicSynonym((Synonym)basionym);
+                                                       basionymName.getHomotypicalGroup().setGroupBasionym(basionymName);
+                                               }
+                                       }
+                               }
+
+
+                       } else{
+                               basionymName = TaxonNameFactory.NewNonViralInstance(name.getRank());
+                               childName = "RelatedName";
+                               obligatory = true;
+                               Element elName = XmlHelp.getSingleChildElement(success, elBasionym, childName, tcsNamespace, obligatory);
+                               String strName = (elName == null)? "" : elName.getTextNormalize();
+                               basionymName.setTitleCache(strName, false);
+                               Synonym basionymSyn = Synonym.NewInstance(basionymName, unknownSec());
+                               if (taxonBase instanceof Taxon){
+                                       Taxon taxon = (Taxon)taxonBase;
+                                       taxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF);
+                                       taxon.getHomotypicGroup().setGroupBasionym(basionymName);
+                                       taxonStore.add(taxon);
+                               } else{
+                                       Synonym syn = (Synonym) taxonBase;
+                                       if (syn.getAcceptedTaxon() != null){
+                                               Taxon accTaxon = syn.getAcceptedTaxon();
+                                               accTaxon.addSynonym(basionymSyn, SynonymType.HOMOTYPIC_SYNONYM_OF);
+                                               accTaxon.getHomotypicGroup().setGroupBasionym(basionymName);
+                                               taxonStore.add(accTaxon);
+                                       }
+                               }
+                       }
+               }
+               return 1;
+       }
+
+       private int makeTaxonConcept(TcsXmlImportState state, MapWrapper<TaxonBase> taxonMap, Set<TaxonBase> taxonStore, Element elTaxonConcept, Namespace tcsNamespace, ResultWrapper<Boolean> success){
+               int taxonRelCount = 0;
+
+               String childName = "TaxonRelationships";
+               boolean obligatory = false;
+               Element elTaxonRelationships = XmlHelp.getSingleChildElement(success, elTaxonConcept, childName, tcsNamespace, obligatory);
+
+               if (elTaxonRelationships != null){
+                       //Relationships
+                       String tcsElementName = "TaxonRelationship";
+                       List<Element> elTaxonRelationshipList = elTaxonRelationships.getChildren(tcsElementName, tcsNamespace);
+                       logger.info("Number of taxonrelationships: " + elTaxonRelationshipList.size());
+                       for (Element elTaxonRelationship: elTaxonRelationshipList){
+
+                               taxonRelCount++;
+                               logger.debug("TaxonRelationship "+  taxonRelCount);
+
+                               String strId = elTaxonConcept.getAttributeValue("id");
+                               //TODO
+//                             String strConceptType = elTaxonConcept.getAttributeValue("type"); //original, revision, incomplete, aggregate, nominal
+//                             String strPrimary = elTaxonConcept.getAttributeValue("primary"); //If primary='true' the concept is the first level response to a query. If 'false' the concept may be a secondary concept linked directly or indirectly to the definition of a primary concept.
+//                             String strForm = elTaxonConcept.getAttributeValue("form");  //anamorph, teleomorph, hybrid
+
+                               TaxonBase fromTaxon = taxonMap.get(removeVersionOfRef(strId));
+                               makeRelationshipType(state, elTaxonRelationship, taxonMap, taxonStore, fromTaxon, success);
+
+                               if (fromTaxon instanceof Taxon){
+                                       makeHomotypicSynonymRelations((Taxon)fromTaxon);
+                               }
+                       }// end Relationship
+               }
+               return taxonRelCount;
+       }
+
+       private int makeTaxonRelationshipAssertion(
+                       TcsXmlImportState state,
+                       MapWrapper<TaxonBase> taxonMap,
+                       MapWrapper<Reference> referenceMap,
+                       Set<TaxonBase> taxonStore,
+                       Element elDataSet,
+                       Namespace tcsNamespace,
+                       ResultWrapper<Boolean> success){
+
+               int i = 0;
+               String childName = "TaxonRelationshipAssertions";
+               boolean obligatory = false;
+               Element elTaxonRelationshipAssertions = XmlHelp.getSingleChildElement(success, elDataSet, childName, tcsNamespace, obligatory);
+               if(elTaxonRelationshipAssertions == null){
+                       return 0;
+               }
+
+               childName = "TaxonRelationshipAssertion";
+               List<Element> elTaxonRelationshipAssertionList = elTaxonRelationshipAssertions.getChildren(childName, tcsNamespace);
+               //for each taxon relationship assertion
+               for (Element elTaxonRelationshipAssertion : elTaxonRelationshipAssertionList){
+                       if ((i++ % modCount) == 0){ logger.info("TaxonRelationshipAssertions handled: " + (i-1));}
+                       String strId = elTaxonRelationshipAssertion.getAttributeValue("id");
+                       //TODO id
+
+                       childName = "AccordingTo";
+                       obligatory = true;
+                       Element elAccordingTo = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
+                       Reference ref = makeAccordingTo(elAccordingTo, referenceMap, success);
+
+                       childName = "FromTaxonConcept";
+                       obligatory = true;
+                       Element elFromTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationshipAssertion, childName, tcsNamespace, obligatory);
+
+                       Class<? extends TaxonBase> clazz = Taxon.class;
+                       //TODO if synonym
+                       TaxonBase fromTaxon = makeReferenceType(elFromTaxonConcept, clazz, taxonMap, success);
+
+                       makeRelationshipType(state, elTaxonRelationshipAssertion, taxonMap, taxonStore, fromTaxon, success);
+               }//elTaxonRelationshipAssertion
+
+               return i;
+       }
+
+
+       /**
+        * Handles the TCS RelationshipType element.
+        * @param tcsConfig
+        * @param elRelationship
+        * @param taxonMap
+        * @param taxonStore
+        * @param fromTaxon
+        * @param success
+        */
+       private void makeRelationshipType(
+                       TcsXmlImportState state
+                       , Element elRelationship
+                       , MapWrapper<TaxonBase> taxonMap
+                       , Set<TaxonBase> taxonStore
+                       , TaxonBase fromTaxon
+                       , ResultWrapper<Boolean> success
+                       ){
+
+               if (elRelationship == null){
+                       success.setValue(false);
+               }
+               String strRelType = elRelationship.getAttributeValue("type");
+
+
+               try {
+                       ResultWrapper<Boolean> isInverse = new ResultWrapper<Boolean>();
+                       isInverse.setValue(false);
+                       if ("has vernacular".equalsIgnoreCase(strRelType)){
+                               handleVernacular(success, state, elRelationship, fromTaxon);
+                       }else{
+                               IRelationshipType relType = TcsXmlTransformer.tcsRelationshipType2Relationship(strRelType, isInverse);
+
+                               //toTaxon (should be part of relationshipType)
+                               boolean isSynonym = (relType instanceof SynonymType);
+                               TaxonBase toTaxon = getToTaxon(elRelationship, taxonMap, state.getMissingConceptLSIDs(), isSynonym, success, state);
+
+                               if (toTaxon != null && fromTaxon != null){
+                                       //exchange taxa if relationship is inverse
+                                       if (isInverse.getValue() == true ){
+                                               TaxonBase tmp = toTaxon;
+                                               toTaxon = fromTaxon;
+                                               fromTaxon = tmp;
+                                       }
+
+                                       //Create relationship
+                                       if (! (toTaxon instanceof Taxon)){
+                                               logger.warn("TaxonBase toTaxon is not of Type 'Taxon'. Relationship is not added.");
+                                               success.setValue(false);
+                                       }else{
+                                               Taxon taxonTo = (Taxon)toTaxon;
+                                               if (relType instanceof SynonymType){
+                                                       SynonymType synRelType = (SynonymType)relType;
+                                                       if (! (fromTaxon instanceof Synonym )){
+                                                               logger.warn("TaxonBase fromTaxon is not of Type 'Synonym'. Relationship is not added.");
+                                                               success.setValue(false);
+                                                       }else{
+                                                               Synonym synonym = (Synonym)fromTaxon;
+                                                               TaxonName synName = synonym.getName();
+                                                               TaxonName accName = taxonTo.getName();
+                                                               if (synName != null && accName != null && synName.isHomotypic(accName)
+                                                                                       && ( synRelType.equals(SynonymType.SYNONYM_OF))){
+                                                                       synRelType = SynonymType.HOMOTYPIC_SYNONYM_OF;
+                                                               }
+                                                               if (! relationExists(taxonTo, synonym, synRelType)){
+                                                                       taxonTo.addSynonym(synonym, synRelType);
+                                                               }else{
+                                                                       //TODO citation, microReference
+                                                                       //TODO different synRelTypes -> warning
+                                                                       success.setValue(false);
+                                                               }
+                                                       }
+                                               }else if (relType instanceof TaxonRelationshipType){
+                                                       Reference citation = null;
+                                                       String microReference = null;
+                                                   makeTaxonRelationship(state, (TaxonRelationshipType)relType, fromTaxon, taxonTo, citation, microReference, success);
+                                               }else{
+                                                       logger.warn("Unknown Relationshiptype");
+                                                       success.setValue(false);
+                                               }
+                                               taxonStore.add(toTaxon);
+                                       }
+                               }else{
+                                       if (toTaxon == null){
+                                       //      logger.warn("toTaxon (" + /*strToTaxon + */ ") could  not be found in taxonMap. Relationship of type " + strRelType + " was not added to CDM");
+                                       }
+                                       if (fromTaxon == null){
+                                       //      logger.warn("fromTaxon (" + /*strTaxonAbout + */") could not be found in taxonMap. Relationship was not added to CDM");
+                                       }
+                                       success.setValue(false);
+                               }
+                       }
+               } catch (UnknownCdmTypeException e) {
+                       //TODO
+                       logger.warn("relationshipType " + strRelType + " not yet implemented");
+                       success.setValue(false);
+               }
+               return;
+       }
+
+       private void handleVernacular(ResultWrapper<Boolean> success, TcsXmlImportState state, Element elRelationship, TaxonBase taxonBase) {
+               if (! taxonBase.isInstanceOf(Taxon.class)){
+                       logger.warn("From Taxon is not of type Taxon but of type " +  taxonBase.getClass().getSimpleName());
+                       success.setValue(false);
+                       return;
+               }else{
+                       Taxon taxon = CdmBase.deproxy(taxonBase, Taxon.class);
+                       Map<String, CommonTaxonName> commonNameMap = state.getCommonNameMap();
+                       CommonTaxonName commonTaxonName = getCommonName(elRelationship, commonNameMap, success);
+                       TaxonDescription description = getDescription(taxon);
+                       description.addElement(commonTaxonName);
+               }
+       }
+
+       private TaxonDescription getDescription(Taxon taxon) {
+               if (taxon.getDescriptions().isEmpty()){
+                       return TaxonDescription.NewInstance(taxon);
+               }else{
+                       //TODO only if the description represents this TCS file
+                       return taxon.getDescriptions().iterator().next();
+               }
+       }
+
+       private CommonTaxonName getCommonName(Element elTaxonRelationship, Map<String, CommonTaxonName> commonNameMap, ResultWrapper<Boolean> success){
+               CommonTaxonName result = null;
+               if (elTaxonRelationship == null || commonNameMap == null){
+                       success.setValue(false);
+               }else{
+                       String childName = "ToTaxonConcept";
+                       boolean obligatory = true;
+                       Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
+
+                       String linkType = elToTaxonConcept.getAttributeValue("linkType");
+                       if (linkType == null || linkType.equals("local")){
+                               String ref = elToTaxonConcept.getAttributeValue("ref");
+                               if (ref != null){
+                                       result = commonNameMap.get(ref);
+                               }else{
+                                       logger.warn("Non ref not yet implemented for vernacular name relationship");
+                               }
+                       }else{
+                               logger.warn("External link types for vernacular name not yet implemented");
+                       }
+               }
+               return result;
+       }
+
+       private void makeTaxonRelationship(TcsXmlImportState state, TaxonRelationshipType relType, TaxonBase fromTaxon, Taxon taxonTo, Reference citation, String microReference, ResultWrapper<Boolean> success){
+               TaxonRelationshipType taxRelType = relType;
+               if (! (fromTaxon instanceof Taxon )){
+                       logger.warn("TaxonBase fromTaxon " + /*strTaxonAbout +*/ "is not of Type 'Taxon'. Relationship is not added.");
+                       success.setValue(false);
+               }else{
+                       Taxon taxonFrom = (Taxon)fromTaxon;
+                       if (relType.equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())){
+                               makeTaxonomicallyIncluded(state, taxonTo, taxonFrom, citation, microReference);
+                       }else{
+                               taxonFrom.addTaxonRelation(taxonTo, taxRelType, citation, microReference);
+                       }
+               }
+       }
+
+       private boolean makeTaxonomicallyIncluded(TcsXmlImportState state, Taxon toTaxon, Taxon fromTaxon, Reference citation, String microCitation){
+               Reference sec = toTaxon.getSec();
+               Classification tree = state.getTree(sec);
+               if (tree == null){
+                       tree = makeTree(state, sec);
+               }
+               TaxonNode childNode = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);
+               return (childNode != null);
+       }
+
+
+       @SuppressWarnings("rawtypes")
+       private TaxonBase getToTaxon(Element elTaxonRelationship, MapWrapper<TaxonBase> map, List<String> missingNameID,boolean isSynonym, ResultWrapper<Boolean> success, TcsXmlImportState state){
+               TaxonBase result = null;
+               if (elTaxonRelationship == null || map == null){
+                       success.setValue(false);
+               }else{
+                       String childName = "ToTaxonConcept";
+                       boolean obligatory = true;
+                       Element elToTaxonConcept = XmlHelp.getSingleChildElement(success, elTaxonRelationship, childName, elTaxonRelationship.getNamespace(), obligatory);
+
+
+                       String linkType = elToTaxonConcept.getAttributeValue("linkType");
+                       if (linkType == null || linkType.equals("local")){
+                               String ref = elToTaxonConcept.getAttributeValue("ref");
+                               if (ref != null){
+                                       result = map.get(ref);
+                                       if (result == null && state.getConfig().isDoGetMissingNames()){
+
+
+                                               String[] split= ref.split(":");
+                                               String id = split[split.length-1];
+                                               logger.info("get name for id " + id);
+                                               if (missingNameID.contains(id)){
+                                                   return null;
+                                               }
+                                               InputStream nameStream = service.getNamesById(id);
+
+
+                                               try{
+                                                       String nameUri = "urn:lsid:ipni.org:names:"+ id;
+                                                       TaxonName name = rdfNameImport.handleRdfElementFromStream(nameStream, rdfConfig, (MapWrapper<TaxonName>)state.getStore(ICdmIO.TAXONNAME_STORE), nameUri);
+                                                       if (name != null){
+                                                               if (name.getTaxa().isEmpty()){
+
+                                                                       result = Taxon.NewInstance(name, null);
+                                                               }else{
+                                                                       result = name.getTaxa().iterator().next();
+                                                               }
+                                                               name.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
+                                                               result.addSource(OriginalSourceType.Import, ref, "TaxonConcept", null, null);
+
+                                                               map.put(removeVersionOfRef(ref), result);
+                                                       } else{
+                                                           missingNameID.add(id);
+                                                       }
+                                               }catch(Exception e){
+                                                       logger.debug(e.getMessage());
+                                                       e.printStackTrace();
+                                               }
+                                       }
+                               }else{
+                                       String title = elToTaxonConcept.getTextNormalize();
+                                       //TODO synonym?
+                                       TaxonName taxonName = TaxonNameFactory.NewNonViralInstance(null);
+                                       taxonName.setTitleCache(title, true);
+                                       logger.warn("Free text related taxon seems to be bug in TCS");
+                                       if (isSynonym){
+                                               result = Synonym.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
+                                       }else{
+                                               result = Taxon.NewInstance(taxonName, TcsXmlTaxonImport.unknownSec());
+                                       }
+                                       result.setTitleCache(title, true);
+                               }
+                       }else{
+                               logger.warn("External link types for synonym not yet implemented");
+                       }
+               }
+               return result;
+       }
+
+       private boolean relationExists(Taxon taxonTo, Synonym synonym, SynonymType synRelType){
+               if (synonym == null || taxonTo == null
+                       || !taxonTo.equals(synonym.getAcceptedTaxon())){
+                       return false;
+               }else{
+                   return CdmUtils.nullSafeEqual(synonym.getType(),synRelType);
+               }
+       }
+
+       private boolean makeHomotypicSynonymRelations(Taxon aboutTaxon){
+               TaxonName aboutName = aboutTaxon.getName();
+               if (aboutName != null){
+                       Set<TaxonName> typifiedNames = aboutName.getHomotypicalGroup().getTypifiedNames();
+                       for (TaxonName typifiedName : typifiedNames){
+                               //TODO check if name is part of this tcs file
+                               if (typifiedName.equals(aboutName)){
+                                       continue;
+                               }
+                               Set<Synonym> syns = typifiedName.getSynonyms();
+                               for(Synonym syn:syns){
+                                       aboutTaxon.addSynonym(syn, SynonymType.HOMOTYPIC_SYNONYM_OF);
+                               }
+                       }
+               }
+               return true;
+       }
+
+       @Override
+    protected boolean isIgnore(TcsXmlImportState state){
+               return ! state.getConfig().isDoRelTaxa();
+       }
+}
\ No newline at end of file