UUIDs changed in FaEu database. Changed hard coded uuid accordingly.
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / faunaEuropaea / FaunaEuropaeaRelTaxonIncludeImport.java
index 4479c25f9740e37c50bd22b994bdbb57b5491704..0e5c266ad91d7fcae4c14d1616521634c41f7170 100644 (file)
 package eu.etaxonomy.cdm.io.faunaEuropaea;\r
 \r
 import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.A_AUCT;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.P_PARENTHESIS;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.Q_NO_RESTRICTION;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_GENUS;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBGENUS;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SPECIES;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.R_SUBSPECIES;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_ACCEPTED;\r
-import static eu.etaxonomy.cdm.io.faunaEuropaea.FaunaEuropaeaTransformer.T_STATUS_NOT_ACCEPTED;\r
 \r
 import java.sql.ResultSet;\r
 import java.sql.SQLException;\r
-import java.util.Collection;\r
 import java.util.HashMap;\r
 import java.util.HashSet;\r
-import java.util.Iterator;\r
 import java.util.List;\r
 import java.util.Map;\r
 import java.util.Set;\r
 import java.util.UUID;\r
 \r
 import org.apache.log4j.Logger;\r
-import org.hibernate.Session;\r
 import org.springframework.stereotype.Component;\r
 import org.springframework.transaction.TransactionStatus;\r
 \r
-import eu.etaxonomy.cdm.api.service.IService;\r
-import eu.etaxonomy.cdm.common.CdmUtils;\r
-import eu.etaxonomy.cdm.io.berlinModel.CdmOneToManyMapper;\r
-import eu.etaxonomy.cdm.io.berlinModel.CdmStringMapper;\r
-import eu.etaxonomy.cdm.io.berlinModel.in.BerlinModelImportState;\r
-import eu.etaxonomy.cdm.io.common.CdmAttributeMapperBase;\r
-import eu.etaxonomy.cdm.io.common.CdmSingleAttributeMapperBase;\r
 import eu.etaxonomy.cdm.io.common.ICdmIO;\r
-import eu.etaxonomy.cdm.io.common.IImportConfigurator;\r
-import eu.etaxonomy.cdm.io.common.ImportHelper;\r
 import eu.etaxonomy.cdm.io.common.MapWrapper;\r
 import eu.etaxonomy.cdm.io.common.Source;\r
 import eu.etaxonomy.cdm.io.profiler.ProfilerController;\r
-import eu.etaxonomy.cdm.io.tcsxml.in.TcsXmlImportState;\r
 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
-import eu.etaxonomy.cdm.model.common.ISourceable;\r
-import eu.etaxonomy.cdm.model.common.IdentifiableEntity;\r
-import eu.etaxonomy.cdm.model.common.OriginalSource;\r
-import eu.etaxonomy.cdm.model.name.Rank;\r
-import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
-import eu.etaxonomy.cdm.model.name.ZoologicalName;\r
-import eu.etaxonomy.cdm.model.reference.Database;\r
-import eu.etaxonomy.cdm.model.reference.Generic;\r
-import eu.etaxonomy.cdm.model.reference.PublicationBase;\r
-import eu.etaxonomy.cdm.model.reference.Publisher;\r
 import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
 import eu.etaxonomy.cdm.model.taxon.Synonym;\r
 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;\r
-import eu.etaxonomy.cdm.strategy.exceptions.UnknownCdmTypeException;\r
-\r
-import com.yourkit.api.Controller;\r
 \r
 \r
 \r
@@ -83,22 +49,13 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
        \r
        public static final String OS_NAMESPACE_TAXON = "Taxon";\r
        private static final Logger logger = Logger.getLogger(FaunaEuropaeaRelTaxonIncludeImport.class);\r
-\r
-       /* Max number of taxa to retrieve (for test purposes) */\r
-       private int maxTaxa = 0;\r
-       /* Max number of taxa to be saved in CDM DB with one service call */\r
-       private int limit = 5000; // TODO: Make configurable\r
-       /* Max number of taxa to be retrieved from CDM DB with one service call */\r
-       private int limitRetrieve = 10000; // TODO: Make configurable\r
-       /* Interval for progress info message when retrieving taxa */\r
-       private int modCount = 10000;\r
-       /* Highest taxon index in the FauEu database */\r
-       private int highestTaxonIndex = 0;\r
-       /* Number of times method buildParentName() has been called for one taxon */\r
-       private int callCount = 0;\r
-       private Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap = new HashMap();\r
-\r
-\r
+       private static final String acceptedTaxonUUID = "A9C24E42-69F5-4681-9399-041E652CF338"; // any accepted taxon uuid, taken from original fauna europaea database\r
+       \r
+       private ReferenceBase<?> sourceRef;\r
+       private static String ALL_SYNONYM_FROM_CLAUSE = " FROM Taxon INNER JOIN Taxon AS Parent " +\r
+       " ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +\r
+       " WHERE (Taxon.TAX_VALID = 0) " +\r
+       " AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL)";\r
 \r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doCheck(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
@@ -117,7 +74,8 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
         * @see eu.etaxonomy.cdm.io.common.CdmIoBase#isIgnore(eu.etaxonomy.cdm.io.common.IImportConfigurator)\r
         */\r
        protected boolean isIgnore(FaunaEuropaeaImportState state) {\r
-               return ! state.getConfig().isDoTaxa();\r
+               return ! (state.getConfig().isDoTaxonomicallyIncluded() || \r
+               state.getConfig().isDoMisappliedNames() || state.getConfig().isDoHeterotypicSynonyms());\r
        }\r
 \r
        private boolean checkTaxonStatus(FaunaEuropaeaImportConfigurator fauEuConfig) {\r
@@ -133,83 +91,103 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
 //             }\r
        }\r
        \r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.io.common.CdmIoBase#doInvoke(eu.etaxonomy.cdm.io.common.IImportConfigurator, eu.etaxonomy.cdm.api.application.CdmApplicationController, java.util.Map)\r
-        */\r
-       protected boolean doInvokeAlter(FaunaEuropaeaImportState state) {                               \r
-               \r
-               boolean success = true;\r
-               \r
-               if(logger.isInfoEnabled()) { logger.info("Start making taxa..."); }\r
-               \r
-//             TransactionStatus txStatus = startTransaction();\r
-               \r
-               success = retrieveTaxa(state, fauEuTaxonMap, Q_NO_RESTRICTION);\r
-               success = processTaxaFromDatabase(state, fauEuTaxonMap);\r
-               \r
-//             commitTransaction(txStatus);\r
-               \r
-               logger.info("End making taxa...");\r
-               return success;\r
-       }\r
-\r
-       \r
        protected boolean doInvoke(FaunaEuropaeaImportState state) {                            \r
                \r
                boolean success = true;\r
+\r
+               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
+\r
+               MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);\r
+               authorStore.makeEmpty();\r
+\r
+               if(logger.isInfoEnabled()) { logger.info("Start making relationships..."); }\r
+\r
+               TransactionStatus txStatus = startTransaction();\r
                \r
+               // the uuid of an accepted taxon is needed here. any accepted taxon will do.\r
+               TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));\r
+               sourceRef = taxon.getSec();\r
 \r
+               TaxonomicTree tree = getTaxonomicTreeFor(state, sourceRef);\r
+               commitTransaction(txStatus);\r
                \r
-                       Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-                       MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-                       taxonStore.makeEmpty();\r
-                       MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);\r
-                       authorStore.makeEmpty();\r
-                       \r
-                       if(logger.isInfoEnabled()) { logger.info("Start making taxonomically included relationships..."); }\r
-                       \r
-       //              TransactionStatus txStatus = startTransaction();\r
-       \r
-                       ProfilerController.memorySnapshot();\r
-                       success = retrieveChildParentUuidMap(state);\r
-                       success = createRelationships(state);\r
-                       ProfilerController.memorySnapshot();\r
-                       \r
-       //              commitTransaction(txStatus);\r
-       \r
-                       logger.info("End making taxa...");\r
+               //ProfilerController.memorySnapshot();\r
+               if (state.getConfig().isDoTaxonomicallyIncluded()) {\r
+                       success = processParentsChildren(state);\r
+               }\r
+               //ProfilerController.memorySnapshot();\r
+               if (state.getConfig().isDoMisappliedNames()) {\r
+                       success = processMisappliedNames(state);\r
+               }\r
+               //ProfilerController.memorySnapshot();\r
+               if (state.getConfig().isDoHeterotypicSynonyms()) {\r
+                       if(logger.isInfoEnabled()) { \r
+                               logger.info("Start making heterotypic synonym relationships..."); \r
+                       }\r
+                       success = processHeterotypicSynonyms(state, ALL_SYNONYM_FROM_CLAUSE);\r
+               }\r
+               //ProfilerController.memorySnapshot();\r
+\r
+               logger.info("End making taxa...");\r
 \r
                return success;\r
        }\r
 \r
        /** Retrieve child-parent uuid map from CDM DB */\r
-       private boolean retrieveChildParentUuidMap(FaunaEuropaeaImportState state) {\r
+       private boolean processParentsChildren(FaunaEuropaeaImportState state) {\r
+\r
+               int limit = state.getConfig().getLimitSave();\r
+\r
+               TransactionStatus txStatus = null;\r
 \r
-               Map<UUID, UUID> childParentMap = state.getChildParentMap();\r
+               Map<UUID, UUID> childParentMap = null;\r
                FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
                Source source = fauEuConfig.getSource();\r
                int i = 0;\r
                boolean success = true;\r
 \r
+               String selectCount = \r
+                       " SELECT count(*) ";\r
+\r
+               String selectColumns = " SELECT Taxon.UUID AS ChildUuid, Parent.UUID AS ParentUuid ";\r
+               \r
+               String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +\r
+               " ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +\r
+               " WHERE (Taxon.TAX_VALID <> 0) AND (Taxon.TAX_AUT_ID <> " + A_AUCT + " OR Taxon.TAX_AUT_ID IS NULL )";\r
+               \r
+               String orderClause = " ORDER BY Taxon.TAX_RNK_ID ASC";\r
+\r
+               String countQuery = \r
+                       selectCount + fromClause;\r
+\r
+               String selectQuery = \r
+                       selectColumns + fromClause + orderClause;\r
+                       \r
+               if(logger.isInfoEnabled()) { logger.info("Start making taxonomically included relationships..."); }\r
+               \r
                try {\r
 \r
-                       String strQuery = \r
-                               " SELECT dbo.Taxon.UUID AS ChildUuid, Parent.UUID AS ParentUuid " +\r
-                               " FROM dbo.Taxon INNER JOIN dbo.Taxon AS Parent " +\r
-                               " ON dbo.Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +\r
-                               " WHERE (dbo.Taxon.TAX_VALID <> 0) AND (dbo.Taxon.TAX_AUT_ID <> " + A_AUCT + ")";\r
+                       ResultSet rs = source.getResultSet(countQuery);\r
+                       rs.next();\r
+                       int count = rs.getInt(1);\r
+                       \r
+                       rs = source.getResultSet(selectQuery);\r
 \r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("Query: " + strQuery);\r
+               if (logger.isInfoEnabled()) {\r
+                               logger.info("Number of rows: " + count);\r
+                               logger.info("Count Query: " + countQuery);\r
+                               logger.info("Select Query: " + selectQuery);\r
                        }\r
 \r
-                       ResultSet rs = source.getResultSet(strQuery);\r
-                       \r
-                       while (rs.next()) {\r
+               while (rs.next()) {\r
                                \r
-                               if ((i++ % modCount) == 0 && i != 1 ) { \r
+                               if ((i++ % limit) == 0) {\r
+                                       \r
+                                       txStatus = startTransaction();\r
+                                       childParentMap = new HashMap<UUID, UUID>(limit);\r
+                                       \r
                                        if(logger.isInfoEnabled()) {\r
-                                               logger.info("Parent-child mappings retrieved: " + (i-1)); \r
+                                               logger.info("Taxonomically included retrieved: " + (i-1)); \r
                                        }\r
                                }\r
 \r
@@ -227,6 +205,17 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
                                                logger.debug("Duplicated child UUID (" + childUuid + ")");\r
                                        }\r
                                }\r
+                               if (((i % limit) == 0 && i != 1 ) || i == count) { \r
+\r
+                                       success = createParentChildRelationships(state, childParentMap);\r
+\r
+                                       childParentMap = null;\r
+                                       commitTransaction(txStatus);\r
+\r
+                                       if(logger.isInfoEnabled()) {\r
+                                               logger.info("i = " + i + " - Transaction committed"); \r
+                                       }\r
+                               }\r
                        }\r
 \r
                } catch (SQLException e) {\r
@@ -235,416 +224,249 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
                }\r
                return success;         \r
        }\r
-\r
        \r
-       /** Retrieve taxa from FauEu DB and build FauEuTaxonMap only */\r
-       private boolean retrieveTaxa(FaunaEuropaeaImportState state,\r
-                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, int valid) {\r
 \r
-               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-               MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-               FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
-               ReferenceBase<?> sourceRef = fauEuConfig.getSourceReference();\r
-               MapWrapper<TeamOrPersonBase> authorStore = (MapWrapper<TeamOrPersonBase>)stores.get(ICdmIO.TEAM_STORE);\r
+       /** Retrieve misapplied name / accepted taxon uuid map from CDM DB */\r
+       private boolean processMisappliedNames(FaunaEuropaeaImportState state) {\r
+\r
+               int limit = state.getConfig().getLimitSave();\r
 \r
+               TransactionStatus txStatus = null;\r
+\r
+               Map<UUID, UUID> childParentMap = null;\r
+               FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
                Source source = fauEuConfig.getSource();\r
-//             String namespace = "Taxon";\r
                int i = 0;\r
                boolean success = true;\r
 \r
-               try {\r
-                       \r
-                       String strQuery = \r
-                               " SELECT MAX(TAX_ID) AS TAX_ID FROM dbo.Taxon ";\r
-                       \r
-                       ResultSet rs = source.getResultSet(strQuery);\r
-                       while (rs.next()) {\r
-                               int maxTaxonId = rs.getInt("TAX_ID");\r
-                               highestTaxonIndex = maxTaxonId;\r
-                       }\r
-                       \r
-            String top = "";\r
-                       if (maxTaxa > 0) {\r
-                               top = "TOP " + maxTaxa;\r
-                       }\r
+               String selectCount = \r
+                       " SELECT count(*) ";\r
+\r
+               String selectColumns = " SELECT Taxon.UUID AS MisappliedUuid, Parent.UUID AS AcceptedUuid ";\r
+               \r
+               String fromClause = " FROM Taxon INNER JOIN Taxon AS Parent " +\r
+               " ON Taxon.TAX_TAX_IDPARENT = Parent.TAX_ID " +\r
+               " WHERE (Taxon.TAX_VALID = 0) AND (Taxon.TAX_AUT_ID = " + A_AUCT + ")";\r
+               \r
+               String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";\r
+\r
+               String countQuery = \r
+                       selectCount + fromClause;\r
+\r
+               String selectQuery = \r
+                       selectColumns + fromClause + orderClause;\r
                        \r
-                       String validClause = "";\r
-                       if (valid == T_STATUS_ACCEPTED || valid == T_STATUS_NOT_ACCEPTED) {\r
-                               validClause = " AND " + " TAX_VALID = " + valid;\r
-                       }\r
+               if(logger.isInfoEnabled()) { logger.info("Start making misapplied name relationships..."); }\r
+\r
+               try {\r
+\r
+                       ResultSet rs = source.getResultSet(countQuery);\r
+                       rs.next();\r
+                       int count = rs.getInt(1);\r
                        \r
-                       strQuery = \r
-                               " SELECT " + top + " Taxon.*, rank.*, author.* " + \r
-                               " FROM dbo.Taxon " +\r
-                               " LEFT OUTER JOIN dbo.author ON dbo.Taxon.TAX_AUT_ID = dbo.author.aut_id " +\r
-                               " LEFT OUTER JOIN dbo.rank ON dbo.Taxon.TAX_RNK_ID = dbo.rank.rnk_id " +\r
-                               " WHERE (1=1)" +\r
-                               validClause;\r
-\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("Query: " + strQuery);\r
+                       rs = source.getResultSet(selectQuery);\r
+\r
+               if (logger.isInfoEnabled()) {\r
+                               logger.info("Number of rows: " + count);\r
+                               logger.info("Count Query: " + countQuery);\r
+                               logger.info("Select Query: " + selectQuery);\r
                        }\r
-                       rs = source.getResultSet(strQuery);\r
-                       \r
-                       while (rs.next()) {\r
 \r
-                               if ((i++ % modCount) == 0 && i != 1 ) { \r
+                       while (rs.next()) {\r
+                               \r
+                               if ((i++ % limit) == 0) {\r
+                                       \r
+                                       txStatus = startTransaction();\r
+                                       childParentMap = new HashMap<UUID, UUID>(limit);\r
+                                       \r
                                        if(logger.isInfoEnabled()) {\r
-                                               logger.info("Taxa retrieved: " + (i-1)); \r
+                                               logger.info("Misapplied names retrieved: " + (i-1) ); \r
                                        }\r
                                }\r
 \r
-                               int taxonId = rs.getInt("TAX_ID");\r
-                               String localName = rs.getString("TAX_NAME");\r
-                               int rankId = rs.getInt("TAX_RNK_ID");\r
-                               int parentId = rs.getInt("TAX_TAX_IDPARENT");\r
-                               int familyId = rs.getInt("TAX_TAX_IDFAMILY");\r
-                               int originalGenusId = rs.getInt("TAX_TAX_IDGENUS");\r
-                               int autId = rs.getInt("TAX_AUT_ID");\r
-                               int status = rs.getInt("TAX_VALID");\r
-                               int year = rs.getInt("TAX_YEAR");\r
-                               int parenthesis = rs.getInt("TAX_PARENTHESIS");\r
-                               String autName = rs.getString("aut_name");\r
-                               Rank rank = null;\r
-//                             UUID taxonBaseUuid = UUID.randomUUID();\r
-\r
-                               FaunaEuropaeaTaxon fauEuTaxon = new FaunaEuropaeaTaxon();\r
-//                             fauEuTaxon.setUuid(taxonBaseUuid);\r
-                               fauEuTaxon.setLocalName(localName);\r
-                               fauEuTaxon.setParentId(parentId);\r
-                               fauEuTaxon.setOriginalGenusId(originalGenusId);\r
-                               fauEuTaxon.setId(taxonId);\r
-                               fauEuTaxon.setRankId(rankId);\r
-                               fauEuTaxon.setYear(year);\r
-                               fauEuTaxon.setAuthor(autName);\r
-                               if (parenthesis == P_PARENTHESIS) {\r
-                                       fauEuTaxon.setParenthesis(true);\r
-                               } else {\r
-                                       fauEuTaxon.setParenthesis(false);\r
-                               }\r
-                               if (status == T_STATUS_ACCEPTED) {\r
-                                       fauEuTaxon.setValid(true);\r
+                               String childUuidStr = rs.getString("MisappliedUuid");\r
+                               String parentUuidStr = rs.getString("AcceptedUuid");\r
+                               UUID childUuid = UUID.fromString(childUuidStr);\r
+                               UUID parentUuid = UUID.fromString(parentUuidStr);\r
+                               \r
+                               if (!childParentMap.containsKey(childUuid)) {\r
+\r
+                                               childParentMap.put(childUuid, parentUuid);\r
+\r
                                } else {\r
-                                       fauEuTaxon.setValid(false);\r
+                                       if(logger.isDebugEnabled()) {\r
+                                               logger.debug("Duplicated child UUID (" + childUuid + ")");\r
+                                       }\r
                                }\r
 \r
-                               try {\r
-                                       rank = FaunaEuropaeaTransformer.rankId2Rank(rs, false);\r
-                               } catch (UnknownCdmTypeException e) {\r
-                                       logger.warn("Taxon (" + taxonId + ") has unknown rank (" + rankId + ") and could not be saved.");\r
-                                       continue;\r
-                               } catch (NullPointerException e) {\r
-                                       logger.warn("Taxon (" + taxonId + ") has rank null and can not be saved.");\r
-                                       continue;\r
-                               }\r
-                               \r
-                               try {\r
-                               \r
-                                                                               \r
-                               if (!fauEuTaxonMap.containsKey(taxonId)) {\r
-                                       if (fauEuTaxon == null) {\r
-                                               if (logger.isDebugEnabled()) { \r
-                                                       logger.debug("Taxon base is null. Taxon (" + taxonId + ") ignored.");\r
-                                               }\r
-                                               continue;\r
-                                       }\r
+                               if (((i % limit) == 0 && i != 1 ) || i == count) { \r
 \r
-                                                       \r
-//                                             taxonStore.put(taxonId, taxonBase);\r
-                                               \r
-                                               fauEuTaxonMap.put(taxonId, fauEuTaxon);\r
-                                               \r
-//                                             if (logger.isDebugEnabled()) { \r
-//                                                     logger.debug("Stored taxon base (" + taxonId + ") " + localName); \r
-//                                             }\r
-                                       } else {\r
-                                               logger.warn("Not imported taxon base with duplicated TAX_ID (" + taxonId + \r
-                                                               ") " + localName);\r
+                                       success = createMisappliedNameRelationships(state, childParentMap);\r
+\r
+                                       childParentMap = null;\r
+                                       commitTransaction(txStatus);\r
+\r
+                                       if(logger.isInfoEnabled()) {\r
+                                               logger.info("i = " + i + " - Transaction committed"); \r
                                        }\r
-                               } catch (Exception e) {\r
-                                       logger.warn("An exception occurred when creating taxon base with id " + taxonId + \r
-                                       ". Taxon base could not be saved.");\r
                                }\r
                        }\r
+\r
                } catch (SQLException e) {\r
                        logger.error("SQLException:" +  e);\r
                        success = false;\r
                }\r
-\r
-               return success;\r
+               return success;         \r
        }\r
 \r
-       \r
-       public Map<UUID, UUID> partMap(int border, Map<UUID, UUID> map) {\r
 \r
-               if (logger.isInfoEnabled()) {\r
-                       logger.info("Map size: " + map.size());\r
-               }\r
-               Set<Map.Entry<UUID, UUID>> entries = map.entrySet();\r
-               Iterator<Map.Entry<UUID, UUID>> entryIter = entries.iterator();\r
-               Map<UUID, UUID> partMap = new HashMap<UUID, UUID>();\r
 \r
-               for (int i = 0; i < border; i++) {\r
-                       //while (entryIter.hasNext()) {\r
+       /** Retrieve synonyms from FauEuDB DB */\r
+       private boolean processHeterotypicSynonyms(FaunaEuropaeaImportState state, String fromClause) {\r
 \r
-                       Map.Entry<UUID, UUID> mapEntry = (Map.Entry<UUID, UUID>)entryIter.next();\r
-                       partMap.put(mapEntry.getKey(), mapEntry.getValue());\r
-                       entryIter.remove();\r
-               }\r
+               FaunaEuropaeaImportConfigurator fauEuConfig = state.getConfig();\r
+               Source source = fauEuConfig.getSource();\r
+               boolean success = true;\r
+\r
+               String selectCount = \r
+                       " SELECT count(*) ";\r
+\r
+               String selectColumns = " SELECT Taxon.UUID AS SynonymUuid, Parent.UUID AS AcceptedUuid ";\r
                \r
-               if (logger.isDebugEnabled()) {\r
-                       logger.debug("Map size: " + map.size());\r
-               }\r
-               return partMap;\r
-       }               \r
-\r
-//     public Map<UUID, UUID> childParentMap partMap(int start, int limit, Map<UUID, UUID> childParentMap) {\r
-//             \r
-//             int index = 0;\r
-//             \r
-//             for (int i = 0; i < limit; i++) {\r
-//                     \r
-//                     int j = start + i;\r
-//                     \r
-//                     Object object = childParentMap.get(j);\r
-//                     if(object != null) {\r
-//                             childParentMap.put(index, childParentMap.get(j));\r
-//                             index++;\r
-//                     } else {\r
-//                             if (logger.isDebugEnabled()) { logger.debug("Object (" + j + ") is null"); }\r
-//                     }\r
-//             }\r
-//             return (Map<UUID, UUID> childParentMap)internalPartMap.values();\r
-//     }\r
+               String orderClause = " ORDER BY dbo.Taxon.TAX_RNK_ID ASC ";\r
 \r
-       \r
-       /** Creates parent-child relationships.\r
-        * Single Parent-child pairs are retrieved via findByUUID(UUID) from CDM DB \r
-        * This takes inacceptable long time. */\r
-       private boolean createRelationships_(FaunaEuropaeaImportState state) {\r
+               String countQuery = \r
+                       selectCount + fromClause;\r
 \r
-               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-               MapWrapper<TaxonBase> taxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-               taxonStore.makeEmpty();\r
-               Map<UUID, UUID> childParentMap = state.getChildParentMap();\r
-               ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();\r
+               String selectQuery = \r
+                       selectColumns + fromClause + orderClause;\r
+               logger.debug(selectQuery);\r
+                       \r
+               try {\r
 \r
-               int upperBorder = childParentMap.size();\r
-               int nbrOfBlocks = 0;\r
+                       ResultSet rs = source.getResultSet(countQuery);\r
+                       rs.next();\r
+                       int count = rs.getInt(1);\r
+                       \r
+                       rs = source.getResultSet(selectQuery);\r
 \r
-               boolean success = true;\r
+               if (logger.isInfoEnabled()) {\r
+                               logger.info("Number of rows: " + count);\r
+                               logger.info("Count Query: " + countQuery);\r
+                               logger.info("Select Query: " + selectQuery);\r
+                       }\r
+               \r
+               success = storeSynonymRelationships(rs, count, state);\r
 \r
-               if (upperBorder < limit) {             // TODO: test with critical values\r
-                       limit = upperBorder;\r
-               } else {\r
-                       nbrOfBlocks = upperBorder / limit;\r
+               } catch (SQLException e) {\r
+                       logger.error("SQLException:" +  e);\r
+                       success = false;\r
                }\r
+               return success;         \r
+       }\r
+       \r
+       \r
 \r
-               if(logger.isInfoEnabled()) { \r
-                       logger.info("number of child-parent pairs = " + upperBorder \r
-                                       + ", limit = " + limit\r
-                                       + ", number of blocks = " + nbrOfBlocks); \r
-               }\r
+       \r
+       private boolean storeSynonymRelationships(ResultSet rs, int count, FaunaEuropaeaImportState state) \r
+       throws SQLException {\r
+\r
+               TransactionStatus txStatus = null;\r
+               Map<UUID, UUID> synonymAcceptedMap = null;\r
+               int i = 0;\r
+               boolean success = true;\r
+               int limit = state.getConfig().getLimitSave();\r
 \r
-               for (int j = 1; j <= nbrOfBlocks + 1; j++) {\r
-                       int offset = j - 1;\r
-                       int start = offset * limit;\r
+               while (rs.next()) {\r
 \r
-                       if(logger.isInfoEnabled()) { logger.info("Processing child-parent pairs: " + start + " - " + (start + limit - 1)); }\r
+                       if ((i++ % limit) == 0) {\r
 \r
-                       if(logger.isInfoEnabled()) { \r
-                               logger.info("index = " + j \r
-                                               + ", offset = " + offset\r
-                                               + ", start = " + start); \r
-                       }\r
+                               txStatus = startTransaction();\r
+                               synonymAcceptedMap = new HashMap<UUID, UUID>(limit);\r
 \r
-                       if (j == nbrOfBlocks + 1) {\r
-                               limit = upperBorder - nbrOfBlocks * limit;\r
-                               if(logger.isInfoEnabled()) { logger.info("number of blocks = " + nbrOfBlocks + " limit = " + limit); }\r
+                               if(logger.isInfoEnabled()) {\r
+                                       logger.info("Synonyms retrieved: " + (i-1)); \r
+                               }\r
                        }\r
 \r
-                       TransactionStatus txStatus = startTransaction();\r
-                       \r
-                       \r
-//                     for (int k = 1; k <= start + offset; k++) {       // TODO: test borders\r
-//                     int k = 0;\r
+                       String synonymUuidStr = rs.getString("SynonymUuid");\r
+                       String acceptedUuidStr = rs.getString("AcceptedUuid");\r
+                       UUID synonymUuid = UUID.fromString(synonymUuidStr);\r
+                       UUID acceptedUuid = UUID.fromString(acceptedUuidStr);\r
 \r
-                       Map<UUID, UUID> childParentPartMap = partMap(limit, childParentMap);\r
-                       Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);\r
-                       \r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("Partmap size: " + childParentPartMap.size());\r
+                       if (!synonymAcceptedMap.containsKey(synonymUuid)) {\r
+\r
+                               synonymAcceptedMap.put(synonymUuid, acceptedUuid);\r
+\r
+                       } else {\r
+                               if(logger.isDebugEnabled()) {\r
+                                       logger.debug("Duplicated synonym UUID (" + synonymUuid + ")");\r
+                               }\r
                        }\r
 \r
-                       for (UUID childUuid : childParentPartMap.keySet()) {\r
-//                     for (UUID childUuid : childParentMap.keySet()) {\r
+                       if (((i % limit) == 0 && i != 1 ) || i == count) { \r
 \r
-                               UUID parentUuid = childParentPartMap.get(childUuid);\r
+                               success = createHeterotypicSynonyms(state, synonymAcceptedMap);\r
 \r
-                               try {\r
-                                       TaxonBase<?> parent = getTaxonService().findByUuid(parentUuid);\r
-                                       if (logger.isTraceEnabled()) {\r
-                                               logger.trace("Parent find called (" + parentUuid + ")");\r
-                                       }\r
-                                       TaxonBase<?> child = getTaxonService().findByUuid(childUuid);\r
-                                       if (logger.isTraceEnabled()) {\r
-                                               logger.trace("Child find called (" + childUuid + ")");\r
-                                       }\r
-                                       Taxon parentTaxon = parent.deproxy(parent, Taxon.class);\r
-                                       Taxon childTaxon = child.deproxy(child, Taxon.class);\r
+                               synonymAcceptedMap = null;\r
+                               commitTransaction(txStatus);\r
 \r
-                                       if (childTaxon != null && parentTaxon != null) {\r
-                                               \r
-//                                             makeTaxonomicallyIncluded(state, parentTaxon, childTaxon, sourceRef, null);\r
-                                               \r
-                                               if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Parent-child (" + parentUuid + "-" + childUuid + \r
-                                                       ") relationship created");\r
-                                               }\r
-                                               if (!childSet.contains(childTaxon)) {\r
-                                                       \r
-                                                       childSet.add(childTaxon);\r
-                                                       \r
-                                                       if (logger.isTraceEnabled()) {\r
-                                                               logger.trace("Child taxon (" + childUuid + ") added to Set");\r
-                                                       }\r
-                                                       \r
-                                               } else {\r
-                                                       if (logger.isDebugEnabled()) {\r
-                                                               logger.debug("Duplicated child taxon (" + childUuid + ")");\r
-                                                       }\r
-                                               }\r
-                                       } else {\r
-                                               if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Parent(" + parentUuid + ") or child (" + childUuid + " is null");\r
-                                               }\r
-                                       }\r
-                                       \r
-//                                     if (childTaxon != null && !childSet.contains(childTaxon)) {\r
-//                                             childSet.add(childTaxon);\r
-//                                             if (logger.isDebugEnabled()) {\r
-//                                                     logger.debug("Child taxon (" + childUuid + ") added to Set");\r
-//                                             }\r
-//                                     } else {\r
-//                                             if (logger.isDebugEnabled()) {\r
-//                                                     logger.debug("Duplicated child taxon (" + childUuid + ")");\r
-//                                             }\r
-//                                     }\r
-                                       \r
-                               } catch (Exception e) {\r
-                                       logger.error("Error creating taxonomically included relationship parent-child (" + \r
-                                                       parentUuid + "-" + childUuid + ")");\r
+                               if(logger.isInfoEnabled()) {\r
+                                       logger.info("i = " + i + " - Transaction committed"); \r
                                }\r
-\r
                        }\r
-                       getTaxonService().saveTaxonAll(childSet);\r
-                       commitTransaction(txStatus);\r
                }\r
                return success;\r
        }\r
-                       \r
-                       \r
+       \r
+       \r
+       \r
+       \r
+\r
        /* Creates parent-child relationships.\r
         * Parent-child pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. \r
-        * It takes about 5min to save a block of 5000 taxa.*/\r
-       private boolean createRelationships(FaunaEuropaeaImportState state) {\r
-\r
-               Map<UUID, UUID> childParentUuidMap = state.getChildParentMap();\r
-               ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();\r
-//             UUID treeUuid = state.getTree(sourceRef).getUuid();\r
-//             TaxonomicTree tree = getTaxonService().getTaxonomicTreeByUuid(treeUuid);\r
-//             TaxonomicTree tree = state.getTree(sourceRef);\r
-\r
-               int upperBorder = childParentUuidMap.size();\r
-               int nbrOfBlocks = 0;\r
-\r
+        */\r
+       private boolean createParentChildRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> childParentMap) {\r
+               //gets the taxon "Hydroscaphidae"(family)\r
+               TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));\r
+               sourceRef = taxon.getSec();\r
                boolean success = true;\r
-\r
-               if (upperBorder < limit) {             // TODO: test with critical values\r
-                       limit = upperBorder;\r
-               } else {\r
-                       nbrOfBlocks = upperBorder / limit;\r
-               }\r
-\r
-               if(logger.isInfoEnabled()) { \r
-                       logger.info("number of child-parent pairs = " + upperBorder \r
-                                       + ", limit = " + limit\r
-                                       + ", number of blocks = " + nbrOfBlocks); \r
-               }\r
-\r
-               for (int j = 1; j <= nbrOfBlocks + 1; j++) {\r
-                       \r
-                       ProfilerController.memorySnapshot();\r
-                       \r
-                       int offset = j - 1;\r
-                       int start = offset * limit;\r
-\r
-                       if(logger.isInfoEnabled()) { logger.info("Processing child-parent pairs: " + start + " - " + (start + limit - 1)); }\r
-\r
-                       if(logger.isInfoEnabled()) { \r
-                               logger.info("index = " + j \r
-                                               + ", offset = " + offset\r
-                                               + ", start = " + start); \r
-                       }\r
-\r
-                       if (j == nbrOfBlocks + 1) {\r
-                               limit = upperBorder - nbrOfBlocks * limit;\r
-                               if(logger.isInfoEnabled()) { logger.info("number of blocks = " + nbrOfBlocks + " limit = " + limit); }\r
-                       }\r
-\r
-                       TransactionStatus txStatus = startTransaction();\r
-                       //add tree to new session\r
-                       TaxonomicTree tree = state.getTree(sourceRef);\r
-                       if (tree == null){\r
-                               tree = makeTree(state, sourceRef);\r
-                       }\r
-                       getTaxonService().saveTaxonomicTree(tree);\r
+               int limit = state.getConfig().getLimitSave();\r
+               \r
+                       TaxonomicTree tree = getTaxonomicTreeFor(state, sourceRef);\r
                        \r
-                       Map<UUID, UUID> childParentPartUuidMap = partMap(limit, childParentUuidMap);\r
                        Set<TaxonBase> childSet = new HashSet<TaxonBase>(limit);\r
                        \r
-                       Set<UUID> childKeysSet = childParentPartUuidMap.keySet();\r
-                       Set<UUID> parentValuesSet = new HashSet<UUID>(childParentPartUuidMap.values());\r
+                       Set<UUID> childKeysSet = childParentMap.keySet();\r
+                       Set<UUID> parentValuesSet = new HashSet<UUID>(childParentMap.values());\r
                        \r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("Start reading children and parents");\r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("Start reading children and parents");\r
                        }\r
-                       List<TaxonBase> children = getTaxonService().findByUuid(childKeysSet);\r
-                       List<TaxonBase> parents = getTaxonService().findByUuid(parentValuesSet);\r
-                       Map<UUID, TaxonBase> parentsMap = new HashMap<UUID, TaxonBase>();\r
+                       List<TaxonBase> children = getTaxonService().find(childKeysSet);\r
+                       List<TaxonBase> parents = getTaxonService().find(parentValuesSet);\r
+                       Map<UUID, TaxonBase> parentsMap = new HashMap<UUID, TaxonBase>(parents.size());\r
                        for (TaxonBase taxonBase : parents){\r
                                parentsMap.put(taxonBase.getUuid(), taxonBase);\r
                        }\r
                        \r
-                       \r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("End reading children and parents");\r
-                       }\r
-                       \r
-                       \r
                        if (logger.isTraceEnabled()) {\r
+                               logger.debug("End reading children and parents");\r
                                for (UUID uuid : childKeysSet) {\r
                                        logger.trace("child uuid query: " + uuid);\r
                                }\r
-                       }\r
-                       if (logger.isTraceEnabled()) {\r
                                for (UUID uuid : parentValuesSet) {\r
                                        logger.trace("parent uuid query: " + uuid);\r
                                }\r
-                       }\r
-                       if (logger.isTraceEnabled()) {\r
                                for (TaxonBase tb : children) {\r
                                        logger.trace("child uuid result: " + tb.getUuid());\r
                                }\r
-                       }\r
-                       if (logger.isTraceEnabled()) {\r
                                for (TaxonBase tb : parents) {\r
                                        logger.trace("parent uuid result: " + tb.getUuid());\r
                                }\r
                        }\r
 \r
                        UUID mappedParentUuid = null;\r
-                       UUID parentUuid = null;\r
                        UUID childUuid = null;\r
 \r
                        for (TaxonBase child : children) {\r
@@ -652,7 +474,7 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
                                try {\r
                                        Taxon childTaxon = child.deproxy(child, Taxon.class);\r
                                        childUuid = childTaxon.getUuid();\r
-                                       mappedParentUuid = childParentPartUuidMap.get(childUuid);\r
+                                       mappedParentUuid = childParentMap.get(childUuid);\r
                                        TaxonBase parent = null;\r
                                        \r
                                        TaxonBase potentialParent = parentsMap.get(mappedParentUuid);\r
@@ -661,7 +483,7 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
 //                                             if(parentUuid.equals(mappedParentUuid)) {\r
                                                        parent = potentialParent;\r
                                                        if (logger.isDebugEnabled()) {\r
-                                                               logger.debug("Parent (" + parentUuid + ") found for child (" + childUuid + ")");\r
+                                                               logger.debug("Parent (" + mappedParentUuid + ") found for child (" + childUuid + ")");\r
                                                        }\r
 //                                                     break;\r
 //                                             }\r
@@ -671,14 +493,13 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
                                        \r
                                        if (childTaxon != null && parentTaxon != null) {\r
                                                \r
-//                                             makeTaxonomicallyIncluded(state, parentTaxon, childTaxon, sourceRef, null, tree);\r
-                                               makeTaxonomicallyIncluded(state, parentTaxon, childTaxon, sourceRef, null);\r
+                                               tree.addParentChild(parentTaxon, childTaxon, sourceRef, null);\r
                                                \r
                                                if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Parent-child (" + parentUuid + "-" + childUuid + \r
+                                                       logger.debug("Parent-child (" + mappedParentUuid + "-" + childUuid + \r
                                                        ") relationship created");\r
                                                }\r
-                                               if (!childSet.contains(childTaxon)) {\r
+                                               if (childTaxon != null && !childSet.contains(childTaxon)) {\r
                                                        \r
                                                        childSet.add(childTaxon);\r
                                                        \r
@@ -693,292 +514,263 @@ public class FaunaEuropaeaRelTaxonIncludeImport extends FaunaEuropaeaImportBase
                                                }\r
                                        } else {\r
                                                if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Parent(" + parentUuid + ") or child (" + childUuid + " is null");\r
-                                               }\r
-                                       }\r
-                                       \r
-                                       if (childTaxon != null && !childSet.contains(childTaxon)) {\r
-                                               childSet.add(childTaxon);\r
-                                               if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Child taxon (" + childUuid + ") added to Set");\r
-                                               }\r
-                                       } else {\r
-                                               if (logger.isDebugEnabled()) {\r
-                                                       logger.debug("Duplicated child taxon (" + childUuid + ")");\r
+                                                       logger.debug("Parent(" + mappedParentUuid + ") or child (" + childUuid + " is null");\r
                                                }\r
                                        }\r
                                        \r
                                } catch (Exception e) {\r
                                        logger.error("Error creating taxonomically included relationship parent-child (" + \r
-                                                       parentUuid + "-" + childUuid + ")");\r
+                                               mappedParentUuid + "-" + childUuid + ")", e);\r
                                }\r
 \r
                        }\r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("Start saving childSet");\r
-                       }\r
-                       getTaxonService().saveTaxonAll(childSet);\r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("End saving childSet");\r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("Start saving childSet");\r
                        }\r
-//                     getTaxonService().clear();\r
-//                     if (logger.isInfoEnabled()) {\r
-//                             logger.info("End clearing session");\r
-//                     }\r
-                       commitTransaction(txStatus);\r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("End commit transaction");\r
+                       getTaxonService().save(childSet);\r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("End saving childSet");\r
                        }\r
+\r
                        parentValuesSet = null;\r
                        childSet = null;\r
-                       childParentPartUuidMap = null;\r
                        children = null;\r
                        parents = null;\r
-               }\r
+                       tree = null;\r
+               \r
                return success;\r
        }\r
 \r
-       \r
-       /* Creates parent-child relationships.\r
-        * Taxon bases are retrieved in blocks from CDM DB.\r
-        * Parent is retrieved from CDM DB via original source id if not found in current block.\r
-        * In case of blocksize = 20.000 this takes ca. 1-2 hours per block.\r
-        *  */\r
-       private boolean createRelationships_old(FaunaEuropaeaTaxon fauEuTaxon,\r
-                       TaxonBase<?> taxonBase, TaxonNameBase<?,?> taxonName, List<Taxon> taxa,\r
-                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap, FaunaEuropaeaImportState state) {\r
-               \r
-               int parentId = fauEuTaxon.getParentId();\r
-               int taxonId = fauEuTaxon.getId();\r
-               FaunaEuropaeaTaxon parentFauEuTaxon = fauEuTaxonMap.get(parentId);\r
-               if (parentFauEuTaxon == null) {\r
-                       if (logger.isInfoEnabled()) {\r
-                               logger.info("Parent taxon is null (" + parentId + ")");\r
-                       }\r
-                       return false;\r
-               }\r
-//             UUID parentUuid = parentFauEuTaxon.getUuid();\r
-               Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-               MapWrapper<TaxonBase> parentTaxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-               ReferenceBase<?> sourceRef = state.getConfig().getSourceReference();\r
+       /* Creates misapplied name relationships.\r
+        * Misapplied name-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. \r
+        */\r
+       private boolean createMisappliedNameRelationships(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {\r
 \r
-               TaxonBase<?> parentTaxonBase = null;\r
-               \r
-//             for (TaxonBase<?> potentialParentTaxon : taxonBases) {\r
-//                     if(potentialParentTaxon.getUuid().equals(parentUuid)) {\r
-//                             parentTaxonBase = potentialParentTaxon;\r
-//                             break;\r
-//                     }\r
-//             }\r
-//             if (parentTaxonBase == null) { \r
-//                     parentTaxonBase = getTaxonService().getTaxonByUuid(parentUuid); \r
-//             }\r
+               //gets the taxon "Hydroscaphidae" (family)\r
                \r
-               // TODO: Copy parents from taxonBases to parentTaxonStore\r
+               TaxonBase taxon = getTaxonService().find(UUID.fromString(acceptedTaxonUUID));\r
+               sourceRef = taxon.getSec();\r
+               boolean success = true;\r
+               int limit = state.getConfig().getLimitSave();\r
                \r
-               if (parentTaxonStore.containsId(parentId)) {\r
-                       parentTaxonBase = parentTaxonStore.get(parentId);\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("Parent (" + parentId + ") found in parent taxon store");\r
+                       Set<TaxonBase> misappliedNameSet = new HashSet<TaxonBase>(limit);\r
+                       \r
+                       Set<UUID> misappliedNamesSet = fromToMap.keySet();\r
+                       Set<UUID> acceptedTaxaSet = new HashSet<UUID>(fromToMap.values());\r
+                       \r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("Start reading misapplied names and accepted taxa");\r
                        }\r
-//             } else {\r
-//                     for (TaxonBase<?> potentialParentTaxon : taxonBases) {\r
-//                             if(potentialParentTaxon.getId() == parentId) {\r
-//                                     parentTaxonBase = potentialParentTaxon;\r
-//                                     if (logger.isInfoEnabled()) {\r
-//                                             logger.info("Parent (" + parentId + ") found in taxon base list");\r
-//                                     }\r
-//                                     break;\r
-//                             }\r
-//                     }\r
-               }\r
-               if (parentTaxonBase == null) {\r
-                       ISourceable sourceable = \r
-                               getCommonService().getSourcedObjectByIdInSource(TaxonBase.class, Integer.toString(parentId), OS_NAMESPACE_TAXON);\r
-                       parentTaxonBase = ((IdentifiableEntity)sourceable).deproxy(sourceable, TaxonBase.class);\r
-                       if (logger.isDebugEnabled()) {\r
-                               logger.debug("Parent (" + parentId + ") retrieved from DB via original source id");\r
+                       List<TaxonBase> misappliedNames = getTaxonService().find(misappliedNamesSet);\r
+                       List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaSet);\r
+                       Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());\r
+                       for (TaxonBase taxonBase : acceptedTaxa){\r
+                               acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);\r
+                       }\r
+                       \r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.info("End reading misapplied names and accepted taxa");\r
+                               for (UUID uuid : misappliedNamesSet) {\r
+                                       logger.trace("misapplied name uuid query: " + uuid);\r
+                               }\r
+                               for (UUID uuid : acceptedTaxaSet) {\r
+                                       logger.trace("accepted taxon uuid query: " + uuid);\r
+                               }\r
+                               for (TaxonBase tb : misappliedNames) {\r
+                                       logger.trace("misapplied name uuid result: " + tb.getUuid());\r
+                               }\r
+                               for (TaxonBase tb : acceptedTaxa) {\r
+                                       logger.trace("accepted taxon uuid result: " + tb.getUuid());\r
+                               }\r
                        }\r
-               }\r
-               \r
-               if (!parentTaxonStore.containsId(parentId)) {\r
-                       parentTaxonStore.put(parentId, parentTaxonBase);\r
-               }\r
-\r
-\r
-               \r
-               Taxon parentTaxon = parentTaxonBase.deproxy(parentTaxonBase, Taxon.class);\r
 \r
-               boolean success = true;\r
-               \r
-//             if (!fauEuTaxon.isValid()) { // FauEu Synonym\r
+                       UUID mappedAcceptedTaxonUuid = null;\r
+                       UUID misappliedNameUuid = null;\r
+                       Taxon misappliedNameTaxon = null;\r
+                       TaxonBase acceptedTaxonBase = null;\r
+                       Taxon acceptedTaxon = null;\r
 \r
-//             } else if (fauEuTaxon.isValid()) { // FauEu Taxon\r
-               \r
-                       Taxon taxon = taxonBase.deproxy(taxonBase, Taxon.class);\r
+                       for (TaxonBase misappliedName : misappliedNames) {\r
 \r
-                       try {\r
-                               // add this taxon as child to parent\r
-                               if (parentTaxon != null) {\r
-//                                     makeTaxonomicallyIncluded(state, parentTaxon, taxon, sourceRef, null);\r
-                                       if (logger.isDebugEnabled()) {\r
-                                               logger.debug("Parent-child (" + parentId + "-" + taxonId + \r
-                                               ") relationship created");\r
+                               try {\r
+                                       misappliedNameTaxon = misappliedName.deproxy(misappliedName, Taxon.class);\r
+                                       misappliedNameUuid = misappliedNameTaxon.getUuid();\r
+                                       mappedAcceptedTaxonUuid = fromToMap.get(misappliedNameUuid);\r
+                                       acceptedTaxonBase = null;\r
+                                       \r
+                                       acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);\r
+                                                       if (logger.isDebugEnabled()) {\r
+                                                               logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + misappliedNameUuid + ")");\r
+                                                       }\r
+                                       \r
+                                                       acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);\r
+                                       \r
+                                       if (misappliedNameTaxon != null && acceptedTaxon != null) {\r
+                                               \r
+                                               acceptedTaxon.addMisappliedName(misappliedNameTaxon, sourceRef, null);\r
+                                       \r
+                                               if (logger.isDebugEnabled()) {\r
+                                                       logger.debug("Accepted taxon / misapplied name (" + mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + \r
+                                                       ") relationship created");\r
+                                               }\r
+                                               if (!misappliedNameSet.contains(misappliedNameTaxon)) {\r
+                                                       \r
+                                                       misappliedNameSet.add(misappliedNameTaxon);\r
+                                                       \r
+                                                       if (logger.isTraceEnabled()) {\r
+                                                               logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");\r
+                                                       }\r
+                                                       \r
+                                               } else {\r
+                                                       if (logger.isDebugEnabled()) {\r
+                                                               logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");\r
+                                                       }\r
+                                               }\r
+                                       } else {\r
+                                               if (logger.isDebugEnabled()) {\r
+                                                       logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + misappliedNameUuid + " is null");\r
+                                               }\r
                                        }\r
+                                       \r
+                                       if (misappliedNameTaxon != null && !misappliedNameSet.contains(misappliedNameTaxon)) {\r
+                                               misappliedNameSet.add(misappliedNameTaxon);\r
+                                               if (logger.isTraceEnabled()) {\r
+                                                       logger.trace("Misapplied name taxon (" + misappliedNameUuid + ") added to Set");\r
+                                               }\r
+                                       } else {\r
+                                               if (logger.isDebugEnabled()) {\r
+                                                       logger.debug("Duplicated misapplied name taxon (" + misappliedNameUuid + ")");\r
+                                               }\r
+                                       }\r
+                                       \r
+                               } catch (Exception e) {\r
+                                       logger.error("Error creating misapplied name relationship accepted taxon-misapplied name (" + \r
+                                               mappedAcceptedTaxonUuid + "-" + misappliedNameUuid + ")", e);\r
                                }\r
 \r
-                       } catch (Exception e) {\r
-                               logger.error("Error creating taxonomically included relationship Parent-child (" + \r
-                                               parentId + "-" + taxonId + ")");\r
                        }\r
-                       \r
-                       \r
-//             }\r
-               \r
-               return success;\r
-       }\r
-       \r
-\r
-       private boolean makeTaxonomicallyIncluded(FaunaEuropaeaImportState state, Taxon toTaxon, Taxon fromTaxon, \r
-                       ReferenceBase citation, String microCitation){\r
-               boolean success = true;\r
-               ReferenceBase sec = toTaxon.getSec();\r
-               sec = CdmBase.deproxy(sec, ReferenceBase.class);\r
-               sec = citation;\r
-               TaxonomicTree tree = state.getTree(sec);\r
-               \r
-               \r
-               \r
-//             Session session = getTaxonService().getSession();\r
-               \r
-//             if (session.contains(sec)) {\r
-//                     logger.debug("Sec contained in session. Id = " + sec.getId());\r
-//             } else {\r
-//                     logger.info("Sec not contained in session. Id = " + sec.getId());\r
-//                     getReferenceService().merge(sec);\r
-//             }\r
-               \r
-               if (tree == null){\r
-                       tree = makeTree(state, sec);\r
-               }\r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("Start saving misappliedNameSet");\r
+                       }\r
+                       getTaxonService().save(misappliedNameSet);\r
+                       if (logger.isTraceEnabled()) {\r
+                               logger.trace("End saving misappliedNameSet");\r
+                       }\r
 \r
-//             if (session.contains(tree)) {\r
-//                     logger.debug("Taxonomic tree contained in session. Id = " + tree.getId());\r
-//             } else {\r
-//                     logger.info("Taxonomic tree not contained in session. Id = " + tree.getId());\r
-//                     UUID treeUuid = state.getTree(sec).getUuid();\r
-//                     tree = getTaxonService().getTaxonomicTreeByUuid(treeUuid);\r
-//                     logger.info("Tree retrieved");\r
-//             }\r
+                       acceptedTaxaSet = null;\r
+                       misappliedNameSet = null;\r
+                       misappliedNames = null;\r
+                       acceptedTaxa = null;\r
                \r
-               success = tree.addParentChild(toTaxon, fromTaxon, citation, microCitation);\r
                return success;\r
        }\r
 \r
        \r
-//     public int calculateBlockSize(int limit, int upperBorder) {\r
-//\r
-//             int blockSize = 0;\r
-//             \r
-//             if (upperBorder < limit) {\r
-//                     limit = upperBorder;\r
-//             } else {\r
-//                     blockSize = upperBorder / limit;\r
-//             }\r
-//     }\r
-       \r
-       \r
-       private boolean processTaxaFromDatabase(FaunaEuropaeaImportState state,\r
-                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {\r
-\r
-               if(logger.isInfoEnabled()) { logger.info("Processing taxa second pass..."); }\r
+       /* Creates heterotypic synonym relationships.\r
+        * Synonym-accepted taxon pairs are retrieved in blocks via findByUUID(Set<UUID>) from CDM DB. \r
+        */\r
+       private boolean createHeterotypicSynonyms(FaunaEuropaeaImportState state, Map<UUID, UUID> fromToMap) {\r
 \r
-               MapWrapper<TaxonBase> taxonBaseMap = new MapWrapper<TaxonBase>(null);\r
+               int limit = state.getConfig().getLimitSave();\r
+               boolean success = true;\r
 \r
-               int nbrOfTaxa = getTaxonService().count(Taxon.class);\r
-               int n = 0;\r
+               Set<TaxonBase> synonymSet = new HashSet<TaxonBase>(limit);\r
 \r
-               boolean success = true;\r
+               Set<UUID> synonymUuidSet = fromToMap.keySet();\r
+               Set<UUID> acceptedTaxaUuidSet = new HashSet<UUID>(fromToMap.values());\r
 \r
-               if (nbrOfTaxa < limit) {             // TODO: test with critical values\r
-                       limit = nbrOfTaxa;\r
-               } else {\r
-                       n = nbrOfTaxa / limit;\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("Reading synonym names and accepted taxa...");\r
                }\r
-\r
-               if(logger.isInfoEnabled()) { \r
-                       logger.info("number of taxa = " + nbrOfTaxa \r
-                                       + ", limit = " + limit\r
-                                       + ", n = " + n); \r
+               List<TaxonBase> synonyms = getTaxonService().find(synonymUuidSet);\r
+               List<TaxonBase> acceptedTaxa = getTaxonService().find(acceptedTaxaUuidSet);\r
+               Map<UUID, TaxonBase> acceptedTaxaMap = new HashMap<UUID, TaxonBase>(acceptedTaxa.size());\r
+               for (TaxonBase taxonBase : acceptedTaxa){\r
+                       acceptedTaxaMap.put(taxonBase.getUuid(), taxonBase);\r
                }\r
 \r
-               // process taxa in chunks of <=limit\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("End reading synonyms names and accepted taxa");\r
+                       for (UUID uuid : synonymUuidSet) {\r
+                               logger.trace("synonym uuid query: " + uuid);\r
+                       }\r
+                       for (UUID uuid : acceptedTaxaUuidSet) {\r
+                               logger.trace("accepted taxon uuid query: " + uuid);\r
+                       }\r
+                       for (TaxonBase tb : synonyms) {\r
+                               logger.trace("synonym uuid result: " + tb.getUuid());\r
+                       }\r
+                       for (TaxonBase tb : acceptedTaxa) {\r
+                               logger.trace("accepted taxon uuid result: " + tb.getUuid());\r
+                       }\r
+               }\r
 \r
-               for (int j = 1; j <= n + 1; j++)\r
-               {\r
-                       int offset = j - 1;\r
-                       int start = offset * limit;\r
+               UUID mappedAcceptedTaxonUuid = null;\r
+               UUID synonymUuid = null;\r
+               Synonym synonym = null;\r
+               TaxonBase acceptedTaxonBase = null;\r
+               Taxon acceptedTaxon = null;\r
 \r
-                       if(logger.isInfoEnabled()) { logger.info("Processing taxa: " + start + " - " + (start + limit - 1)); }\r
+               for (TaxonBase synonymTaxonBase : synonyms) {\r
 \r
-                       if(logger.isInfoEnabled()) { \r
-                               logger.info("index = " + j \r
-                                               + ", offset = " + offset\r
-                                               + ", start = " + start); \r
-                       }\r
+                       try {\r
+                               synonym = synonymTaxonBase.deproxy(synonymTaxonBase, Synonym.class);\r
+                               synonymUuid = synonym.getUuid();\r
+                               mappedAcceptedTaxonUuid = fromToMap.get(synonymUuid);\r
+                               acceptedTaxonBase = null;\r
+\r
+                               acceptedTaxonBase = acceptedTaxaMap.get(mappedAcceptedTaxonUuid);\r
+                               if (logger.isDebugEnabled()) {\r
+                                       logger.debug("Parent (" + mappedAcceptedTaxonUuid + ") found for child (" + synonymUuid + ")");\r
+                               }\r
+                               acceptedTaxon = acceptedTaxonBase.deproxy(acceptedTaxonBase, Taxon.class);\r
 \r
-                       if (j == n + 1) {\r
-                               limit = nbrOfTaxa - n * limit;\r
-                               if(logger.isInfoEnabled()) { logger.info("n = " + n + " limit = " + limit); }\r
-                       }\r
+                               if (synonym != null && acceptedTaxon != null) {\r
 \r
-               TransactionStatus txStatus = startTransaction();\r
-               \r
-                       List<Taxon> taxa = getTaxonService().getAllTaxa(limit, start);\r
-                       if(logger.isInfoEnabled()) { \r
-                               logger.info(taxa.size() +  " taxa retrieved from CDM DB"); \r
-                       }\r
+                                       //TODO: in case original genus exists must add synonym to original genus instead of to accepted taxon\r
+                                       acceptedTaxon.addSynonym(synonym, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF());\r
 \r
-                       for (TaxonBase taxonBase : taxa) {\r
+                                       if (logger.isDebugEnabled()) {\r
+                                               logger.debug("Accepted taxon - synonym (" + mappedAcceptedTaxonUuid + " - " + synonymUuid + \r
+                                               ") relationship created");\r
+                                       }\r
+                                       if (synonym != null && !synonymSet.contains(synonym)) {\r
 \r
-                               TaxonNameBase<?,?> taxonName = taxonBase.getName();\r
+                                               synonymSet.add(synonym);\r
 \r
-                               FaunaEuropaeaTaxon fauEuTaxon = findFauEuTaxonByOriginalSourceId(taxonBase, fauEuTaxonMap);\r
-                               \r
+                                               if (logger.isTraceEnabled()) {\r
+                                                       logger.trace("Synonym (" + synonymUuid + ") added to Set");\r
+                                               }\r
 \r
-                               if (logger.isDebugEnabled()) { \r
-                                       logger.debug("Taxon # " + fauEuTaxon.getId()); \r
+                                       } else {\r
+                                               if (logger.isDebugEnabled()) {\r
+                                                       logger.debug("Duplicated synonym (" + synonymUuid + ")");\r
+                                               }\r
+                                       }\r
+                               } else {\r
+                                       if (logger.isDebugEnabled()) {\r
+                                               logger.debug("Accepted taxon (" + mappedAcceptedTaxonUuid + ") or misapplied name (" + synonymUuid + " is null");\r
+                                       }\r
                                }\r
-                               //createRelationships(fauEuTaxon, taxonBase, taxonName, taxa, fauEuTaxonMap, state);\r
+                       } catch (Exception e) {\r
+                               logger.error("Error creating synonym relationship: accepted taxon-synonym (" + \r
+                                               mappedAcceptedTaxonUuid + "-" + synonymUuid + ")", e);\r
                        }\r
-\r
-                       getTaxonService().saveTaxonAll(taxa);\r
-                       taxa = null;\r
-                       \r
-                       commitTransaction(txStatus);\r
-                       \r
-                       // empty parent taxon store\r
-//                     Map<String, MapWrapper<? extends CdmBase>> stores = state.getStores();\r
-//                     MapWrapper<TaxonBase> parentTaxonStore = (MapWrapper<TaxonBase>)stores.get(ICdmIO.TAXON_STORE);\r
-//                     parentTaxonStore.makeEmpty();\r
                }\r
-               return success;\r
-       }\r
-\r
-\r
-       private FaunaEuropaeaTaxon findFauEuTaxonByOriginalSourceId(TaxonBase<?> taxonBase, \r
-                       Map<Integer, FaunaEuropaeaTaxon> fauEuTaxonMap) {\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("Start saving synonymSet");\r
+               }\r
+               getTaxonService().save(synonymSet);\r
+               if (logger.isTraceEnabled()) {\r
+                       logger.trace("End saving synonymSet");\r
+               }\r
 \r
-               Set set = taxonBase.getSources();\r
-               Object[] array = set.toArray();\r
-               if (array.length == 0) { return null; }\r
-               OriginalSource os = (OriginalSource) taxonBase.getSources().toArray()[0];\r
-               String taxonBaseIdStr = os.getIdInSource();\r
-               int taxonBaseId = Integer.parseInt(taxonBaseIdStr);\r
-               FaunaEuropaeaTaxon fauEuTaxon = fauEuTaxonMap.get(taxonBaseId); \r
+               acceptedTaxaUuidSet = null;\r
+               synonymSet = null;\r
+               synonyms = null;\r
+               acceptedTaxa = null;\r
 \r
-               return fauEuTaxon;\r
+               return success;\r
        }\r
 \r
-       \r
 }\r