cleanup
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / specimen / SpecimenImportBase.java
index db92c0f27f75e96ca859e08124b619d9f2d86c4a..9856e52a465f7ce6bf801b76266ba397090af5ee 100755 (executable)
@@ -6,11 +6,10 @@
 * 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.specimen;
 
-
 import java.util.ArrayList;
+import java.util.EnumSet;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -18,12 +17,13 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
 
 import eu.etaxonomy.cdm.api.application.ICdmRepository;
-import eu.etaxonomy.cdm.api.facade.DerivedUnitFacade;
 import eu.etaxonomy.cdm.api.service.config.FindOccurrencesConfigurator;
 import eu.etaxonomy.cdm.api.service.pager.Pager;
+import eu.etaxonomy.cdm.facade.DerivedUnitFacade;
 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
 import eu.etaxonomy.cdm.io.common.CdmImportBase;
 import eu.etaxonomy.cdm.io.common.IImportConfigurator;
@@ -34,19 +34,18 @@ import eu.etaxonomy.cdm.model.agent.Institution;
 import eu.etaxonomy.cdm.model.agent.Person;
 import eu.etaxonomy.cdm.model.agent.Team;
 import eu.etaxonomy.cdm.model.common.CdmBase;
-import eu.etaxonomy.cdm.model.common.ISourceable;
 import eu.etaxonomy.cdm.model.common.IdentifiableSource;
 import eu.etaxonomy.cdm.model.common.LanguageString;
-import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
-import eu.etaxonomy.cdm.model.common.OriginalSourceType;
 import eu.etaxonomy.cdm.model.description.DescriptionBase;
 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
+import eu.etaxonomy.cdm.model.description.DescriptionType;
 import eu.etaxonomy.cdm.model.description.Feature;
 import eu.etaxonomy.cdm.model.description.IndividualsAssociation;
 import eu.etaxonomy.cdm.model.description.TaxonDescription;
 import eu.etaxonomy.cdm.model.name.INonViralName;
 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
 import eu.etaxonomy.cdm.model.name.Rank;
+import eu.etaxonomy.cdm.model.name.RankClass;
 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignation;
 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
 import eu.etaxonomy.cdm.model.name.TaxonName;
@@ -56,6 +55,9 @@ import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
 import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationType;
+import eu.etaxonomy.cdm.model.reference.ISourceable;
+import eu.etaxonomy.cdm.model.reference.OriginalSourceBase;
+import eu.etaxonomy.cdm.model.reference.OriginalSourceType;
 import eu.etaxonomy.cdm.model.reference.Reference;
 import eu.etaxonomy.cdm.model.reference.ReferenceFactory;
 import eu.etaxonomy.cdm.model.taxon.Classification;
@@ -63,39 +65,37 @@ import eu.etaxonomy.cdm.model.taxon.Synonym;
 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.term.DefinedTerm;
 import eu.etaxonomy.cdm.persistence.query.MatchMode;
 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
 import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
 import eu.etaxonomy.cdm.strategy.parser.TimePeriodParser;
 
-
 /**
  * @author p.kelbert
- * @created 20.10.2008
+ * @since 20.10.2008
  */
 public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STATE extends SpecimenImportStateBase>
         extends CdmImportBase<CONFIG, STATE> {
 
     private static final long serialVersionUID = 4423065367998125678L;
-    private static final Logger logger = Logger.getLogger(SpecimenImportBase.class);
+    private static final Logger logger = LogManager.getLogger();
 
        protected static final UUID SPECIMEN_SCAN_TERM = UUID.fromString("acda15be-c0e2-4ea8-8783-b9b0c4ad7f03");
 
        private static final String COLON = ":";
 
+       protected Map<String, DefinedTerm> kindOfUnitsMap;
+
 
        @Override
     protected abstract void doInvoke(STATE state);
 
        /**
         * Handle a single unit
-        * @param state
-        * @param item
         */
        protected abstract void handleSingleUnit(STATE state, Object item) ;
 
-
-
        protected TaxonName getOrCreateTaxonName(String scientificName, Rank rank, boolean preferredFlag, STATE state, int unitIndexInAbcdFile){
            TaxonName taxonName = null;
         SpecimenImportConfiguratorBase<?,?,?> config = state.getConfig();
@@ -131,15 +131,15 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
 
             } else {
                 //search for existing names
-                List<TaxonName> names = getNameService().listByTitle(TaxonName.class, scientificName, MatchMode.EXACT, null, null, null, null, null);
+                List<TaxonName> names = getNameService().listByTitleWithRestrictions(TaxonName.class, scientificName, MatchMode.EXACT, null, null, null, null, null);
                 taxonName = getBestMatchingName(scientificName, names, state);
                 //still nothing found -> try with the atomised name full title cache
                 if(taxonName==null && atomisedTaxonName!=null){
-                    names = getNameService().listByTitle(TaxonName.class, atomisedTaxonName.getFullTitleCache(), MatchMode.EXACT, null, null, null, null, null);
+                    names = getNameService().listByTitleWithRestrictions(TaxonName.class, atomisedTaxonName.getFullTitleCache(), MatchMode.EXACT, null, null, null, null, null);
                     taxonName = getBestMatchingName(atomisedTaxonName.getTitleCache(), names, state);
                     //still nothing found -> try with the atomised name title cache
                     if(taxonName==null){
-                        names = getNameService().listByTitle(TaxonName.class, atomisedTaxonName.getTitleCache(), MatchMode.EXACT, null, null, null, null, null);
+                        names = getNameService().listByTitleWithRestrictions(TaxonName.class, atomisedTaxonName.getTitleCache(), MatchMode.EXACT, null, null, null, null, null);
                         taxonName = getBestMatchingName(atomisedTaxonName.getTitleCache(), names, state);
                     }
                 }
@@ -174,7 +174,12 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             state.getReport().addName(taxonName);
             logger.info("Created new taxon name "+taxonName);
         }
-        save(taxonName, state);
+        if (taxonName != null){
+            state.names.put(taxonName.getNameCache(), taxonName);
+        }
+        if(!taxonName.isPersisted()) {
+            save(taxonName, state);
+        }
         return taxonName;
     }
 
@@ -182,22 +187,27 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                Set<TaxonName> namesWithAcceptedTaxa = new HashSet<>();
                List<TaxonName> namesWithAcceptedTaxaInClassification = new ArrayList<>();
                for (TaxonName name : names) {
-                   if(!name.getTaxa().isEmpty()){
-                       Set<Taxon> taxa = name.getTaxa();
-                       for (Taxon taxon:taxa){
-                           if (!taxon.getTaxonNodes().isEmpty()){
+                   if(!name.getTaxonBases().isEmpty()){
+                       Set<TaxonBase> taxa = name.getTaxonBases();
+                       for (TaxonBase taxonBase:taxa){
+                           Taxon acceptedTaxon= null;
+                           if (taxonBase instanceof Synonym) {
+                               Synonym syn = (Synonym) taxonBase;
+                               acceptedTaxon = syn.getAcceptedTaxon();
+                           }else {
+                               acceptedTaxon = (Taxon)taxonBase;
+                           }
+                           if (!(acceptedTaxon).getTaxonNodes().isEmpty()){
                                //use only taxa included in a classification
-                               for (TaxonNode node:taxon.getTaxonNodes()){
+                               for (TaxonNode node:(acceptedTaxon).getTaxonNodes()){
                                    if (state.getClassification() != null && node.getClassification().equals(state.getClassification())){
                                        namesWithAcceptedTaxaInClassification.add(name);
                                    }else {
                                        namesWithAcceptedTaxa.add(name);
                                    }
                                }
-
                            }
                        }
-
                    }
                }
                String message = String.format("More than one taxon name was found for %s, maybe in other classifications!", scientificName);
@@ -221,25 +231,25 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    }
                    return namesWithAcceptedTaxa.iterator().next();
                }
-               //no names with accepted taxa found -> check accepted taxa of synonyms
-               List<Taxon> taxaFromSynonyms = new ArrayList<>();
-               for (TaxonName name : names) {
-                   Set<TaxonBase> taxonBases = name.getTaxonBases();
-                   for (TaxonBase taxonBase : taxonBases) {
-                       if(taxonBase.isInstanceOf(Synonym.class)){
-                           Synonym synonym = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
-                           taxaFromSynonyms.add(synonym.getAcceptedTaxon());
-                       }
-                   }
-               }
-               if(taxaFromSynonyms.size()>0){
-                   if(taxaFromSynonyms.size()>1){
-                       state.getReport().addInfoMessage(message);
-                       logger.warn(message);
-                       return null;
-                   }
-                   return taxaFromSynonyms.iterator().next().getName();
-               }
+//             //no names with accepted taxa found -> check accepted taxa of synonyms -> this is handled in the first block now!
+//             List<Taxon> taxaFromSynonyms = new ArrayList<>();
+//             for (TaxonName name : names) {
+//                 Set<TaxonBase> taxonBases = name.getTaxonBases();
+//                 for (TaxonBase taxonBase : taxonBases) {
+//                     if(taxonBase.isInstanceOf(Synonym.class)){
+//                         Synonym synonym = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
+//                         taxaFromSynonyms.add(synonym.getAcceptedTaxon());
+//                     }
+//                 }
+//             }
+//             if(taxaFromSynonyms.size()>0){
+//                 if(taxaFromSynonyms.size()>1){
+//                     state.getReport().addInfoMessage(message);
+//                     logger.warn(message);
+//                     return null;
+//                 }
+//                 return taxaFromSynonyms.iterator().next().getName();
+//             }
                //no accepted and no synonyms -> return one of the names and create a new taxon
                if (names.isEmpty()){
                    return null;
@@ -247,6 +257,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    return names.iterator().next();
                }
            }
+
         /**
             * Parse automatically the scientific name
             * @param scientificName the scientific name to parse
@@ -254,7 +265,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             * @param report the import report
             * @return a parsed name
             */
-
            protected TaxonName parseScientificName(String scientificName, STATE state, SpecimenImportReport report, Rank rank) {
 
                NonViralNameParserImpl nvnpi = NonViralNameParserImpl.NewInstance();
@@ -265,25 +275,25 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    logger.debug("parseScientificName " + state.getDataHolder().getNomenclatureCode().toString());
                }
 
-               if (state.getDataHolder().getNomenclatureCode().toString().equals("Zoological") || state.getDataHolder().getNomenclatureCode().toString().contains("ICZN")) {
+               if (state.getDataHolder().getNomenclatureCode() != null && (state.getDataHolder().getNomenclatureCode().toString().equals("Zoological") || state.getDataHolder().getNomenclatureCode().toString().contains("ICZN"))) {
                    taxonName = (TaxonName)nvnpi.parseFullName(scientificName, NomenclaturalCode.ICZN, rank);
                    if (taxonName.hasProblem()) {
                        problem = true;
                    }
                }
-               else if (state.getDataHolder().getNomenclatureCode().toString().equals("Botanical") || state.getDataHolder().getNomenclatureCode().toString().contains("ICBN")) {
+               else if (state.getDataHolder().getNomenclatureCode() != null && (state.getDataHolder().getNomenclatureCode().toString().equals("Botanical") || state.getDataHolder().getNomenclatureCode().toString().contains("ICBN")  || state.getDataHolder().getNomenclatureCode().toString().contains("ICNAFP"))) {
                    taxonName = (TaxonName)nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNAFP, rank);
                    if (taxonName.hasProblem()) {
                        problem = true;
                    }
                }
-               else if (state.getDataHolder().getNomenclatureCode().toString().equals("Bacterial") || state.getDataHolder().getNomenclatureCode().toString().contains("ICBN")) {
-                   taxonName = (TaxonName)nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNB, rank);
+               else if (state.getDataHolder().getNomenclatureCode() != null && (state.getDataHolder().getNomenclatureCode().toString().equals("Bacterial") || state.getDataHolder().getNomenclatureCode().toString().contains("ICBN"))) {
+                   taxonName = (TaxonName)nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNP, rank);
                    if (taxonName.hasProblem()) {
                        problem = true;
                    }
                }
-               else if (state.getDataHolder().getNomenclatureCode().toString().equals("Cultivar") || state.getDataHolder().getNomenclatureCode().toString().contains("ICNCP")) {
+               else if (state.getDataHolder().getNomenclatureCode() != null && (state.getDataHolder().getNomenclatureCode().toString().equals("Cultivar") || state.getDataHolder().getNomenclatureCode().toString().contains("ICNCP"))) {
                    taxonName = (TaxonName)nvnpi.parseFullName(scientificName, NomenclaturalCode.ICNCP, rank);
                    if (taxonName.hasProblem()) {
                        problem = true;
@@ -390,7 +400,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    taxonName.setSpecificEpithet(NB(getFromMap(atomisedMap, "FirstEpithet")));
                    taxonName.setInfraSpecificEpithet(NB(getFromMap(atomisedMap, "InfraSpeEpithet")));
                    try {
-                       taxonName.setRank(Rank.getRankByName(getFromMap(atomisedMap, "Rank")));
+                       taxonName.setRank(Rank.getRankByLatinName(getFromMap(atomisedMap, "Rank")));
                    } catch (Exception e) {
                        if (taxonName.getInfraSpecificEpithet() != null){
                            taxonName.setRank(Rank.SUBSPECIES());
@@ -437,7 +447,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                        return taxonName;
                    }
                }
-               else if (state.getDataHolder().getNomenclatureCode().equals("Bacterial") || state.getDataHolder().getNomenclatureCode().equals(NomenclaturalCode.ICNB.getUuid())) {
+               else if (state.getDataHolder().getNomenclatureCode().equals("Bacterial") || state.getDataHolder().getNomenclatureCode().equals(NomenclaturalCode.ICNP.getUuid())) {
                    TaxonName taxonName = TaxonNameFactory.NewBacterialInstance(null);
                    taxonName.setFullTitleCache(fullName, true);
                    taxonName.setGenusOrUninomial(getFromMap(atomisedMap, "Genus"));
@@ -469,7 +479,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                        taxonName.setBasionymAuthorship(team);
                    }
                    if (taxonName.hasProblem()) {
-                       logger.info("pb ICNB");
+                       logger.info("pb ICNP");
                        problem = true;
                    }
                    else {
@@ -537,14 +547,11 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
 
            /**
             * Very fast and dirty implementation to allow handling of transient objects as described in
-            * https://dev.e-taxonomy.eu/trac/ticket/3726
+            * https://dev.e-taxonomy.eu/redmine/issues/3726
             *
             * Not yet complete.
-            *
-            * @param cdmBase
-            * @param state
             */
-           protected UUID save(CdmBase cdmBase, SpecimenImportStateBase state) {
+           protected UUID save(CdmBase cdmBase, SpecimenImportStateBase<?,?> state) {
                ICdmRepository cdmRepository = state.getConfig().getCdmAppController();
                if (cdmRepository == null){
                    cdmRepository = this;
@@ -553,7 +560,8 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                if (cdmBase.isInstanceOf(LanguageString.class)){
                    return cdmRepository.getTermService().saveLanguageData(CdmBase.deproxy(cdmBase, LanguageString.class));
                }else if (cdmBase.isInstanceOf(SpecimenOrObservationBase.class)){
-                   return cdmRepository.getOccurrenceService().saveOrUpdate(CdmBase.deproxy(cdmBase, SpecimenOrObservationBase.class));
+                   SpecimenOrObservationBase<?> specimen = CdmBase.deproxy(cdmBase, SpecimenOrObservationBase.class);
+                   return cdmRepository.getOccurrenceService().saveOrUpdate(specimen);
                }else if (cdmBase.isInstanceOf(Reference.class)){
                    return cdmRepository.getReferenceService().saveOrUpdate(CdmBase.deproxy(cdmBase, Reference.class));
                }else if (cdmBase.isInstanceOf(Classification.class)){
@@ -563,7 +571,8 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                }else if (cdmBase.isInstanceOf(Collection.class)){
                    return cdmRepository.getCollectionService().saveOrUpdate(CdmBase.deproxy(cdmBase, Collection.class));
                }else if (cdmBase.isInstanceOf(DescriptionBase.class)){
-                   return cdmRepository.getDescriptionService().saveOrUpdate(CdmBase.deproxy(cdmBase, DescriptionBase.class));
+                   DescriptionBase<?> description = CdmBase.deproxy(cdmBase, DescriptionBase.class);
+                   return cdmRepository.getDescriptionService().saveOrUpdate(description);
                }else if (cdmBase.isInstanceOf(TaxonBase.class)){
                    return cdmRepository.getTaxonService().saveOrUpdate(CdmBase.deproxy(cdmBase, TaxonBase.class));
                }else if (cdmBase.isInstanceOf(TaxonName.class)){
@@ -573,23 +582,35 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             }else{
                    throw new IllegalArgumentException("Class not supported in save method: " + CdmBase.deproxy(cdmBase, CdmBase.class).getClass().getSimpleName());
                }
-
            }
 
-
-           protected SpecimenOrObservationBase findExistingSpecimen(String unitId, SpecimenImportStateBase state){
+           protected SpecimenOrObservationBase<?> findExistingSpecimen(String unitId, SpecimenImportStateBase<?,?> state){
                ICdmRepository cdmAppController = state.getConfig().getCdmAppController();
                if(cdmAppController==null){
                    cdmAppController = this;
                }
                FindOccurrencesConfigurator config = new FindOccurrencesConfigurator();
                config.setSignificantIdentifier(unitId);
-               Pager<SpecimenOrObservationBase> existingSpecimens = cdmAppController.getOccurrenceService().findByTitle(config);
-               if(!existingSpecimens.getRecords().isEmpty()){
-                   if(existingSpecimens.getRecords().size()==1){
-                       return existingSpecimens.getRecords().iterator().next();
-                   }
+               List<String> propertyPaths = new ArrayList<>();
+               propertyPaths.add("derivedFrom.*");
+               config.setPropertyPaths(propertyPaths);
+               commitTransaction(state.getTx());
+               state.setTx(startTransaction());
+               try{
+                       @SuppressWarnings("rawtypes")
+                Pager<SpecimenOrObservationBase> existingSpecimens = cdmAppController.getOccurrenceService().findByTitle(config);
+                       if(!existingSpecimens.getRecords().isEmpty()){
+                           if(existingSpecimens.getRecords().size()==1){
+                               return existingSpecimens.getRecords().iterator().next();
+                           }
+                       }
+
+               }catch(NullPointerException e){
+                       logger.error("searching for existing specimen creates NPE: " + config.getSignificantIdentifier());
+                       e.printStackTrace();
                }
+
+
                return null;
            }
 
@@ -641,7 +662,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             * @return the Institution (existing or new)
             */
            protected Institution getInstitution(String institutionCode, STATE state) {
-               SpecimenImportConfiguratorBase config = state.getConfig();
+               SpecimenImportConfiguratorBase<?,?,?> config = state.getConfig();
                Institution institution=null;
                institution = (Institution)state.institutions.get(institutionCode);
                if (institution != null){
@@ -675,10 +696,9 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    institution = Institution.NewInstance();
                    institution.setCode(institutionCode);
                    institution.setTitleCache(institutionCode, true);
-                   UUID uuid = save(institution, state);
+                   save(institution, state);
                }
 
-
                state.institutions.put(institutionCode, institution);
                return institution;
            }
@@ -691,7 +711,8 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             * @return the Collection (existing or new)
             */
            protected Collection getCollection(Institution institution, String collectionCode, STATE state) {
-               SpecimenImportConfiguratorBase config = state.getConfig();
+
+               SpecimenImportConfiguratorBase<?,?,?> config = state.getConfig();
                Collection collection = null;
                List<Collection> collections;
                collection = (Collection) state.collections.get(collectionCode);
@@ -701,7 +722,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                try {
                    collections = getCollectionService().searchByCode(collectionCode);
                } catch (Exception e) {
-                   collections = new ArrayList<Collection>();
+                   collections = new ArrayList<>();
                }
                if (collections.size() > 0 && config.isReuseExistingMetaData()) {
                    for (Collection coll:collections){
@@ -717,12 +738,9 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    collection =Collection.NewInstance();
                    collection.setCode(collectionCode);
                    collection.setInstitute(institution);
-                   collection.setTitleCache(collectionCode);
-                   UUID uuid = save(collection, state);
+                   save(collection, state);
                }
 
-
-
                state.collections.put(collectionCode, collection);
 
                return collection;
@@ -741,28 +759,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
            //    for our new source.
            protected IdentifiableSource getIdentifiableSource(Reference reference, String citationDetail) {
 
-             /*  List<IdentifiableSource> issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
-
-
-               if (reference != null){
-                   try {
-                       for (OriginalSourceBase<?> osb: issTmp){
-                           if (osb.getCitation() != null && osb.getCitation().getTitleCache().equalsIgnoreCase(reference.getTitleCache())){
-                               String osbDetail = osb.getCitationMicroReference();
-                               if ((StringUtils.isBlank(osbDetail) && StringUtils.isBlank(citationDetail))
-                                       || (osbDetail != null && osbDetail.equalsIgnoreCase(citationDetail)) ) {
-//                                 System.out.println("REFERENCE FOUND RETURN EXISTING SOURCE");
-                                   return (IdentifiableSource) osb.clone();
-                               }
-                           }
-                       }
-                   } catch (CloneNotSupportedException e) {
-                       throw new RuntimeException(e);
-                   } catch (Exception e1){
-                       e1.printStackTrace();
-                   }
-               }
-       */
                IdentifiableSource sour = IdentifiableSource.NewInstance(OriginalSourceType.Import,null,null, reference,citationDetail);
                return sour;
            }
@@ -782,7 +778,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                Taxon subspecies = null;
                Taxon parent = null;
                if(rank!=null){
-                   if (rank.isLower(Rank.GENUS() )){
+                   if (rank.isLowerThan(RankClass.Genus)){
                        String genusOrUninomial = nvname.getGenusOrUninomial();
                        TaxonName taxonName = getOrCreateTaxonName(genusOrUninomial, Rank.GENUS(), preferredFlag, state, -1);
                        genus = getOrCreateTaxonForName(taxonName, state);
@@ -802,9 +798,10 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                            subgenus = getOrCreateTaxonForName(taxonName, state);
                            if (preferredFlag) {
                                parent = linkParentChildNode(genus, subgenus, classification, state);
-                           }            }
+                           }
+                       }
                    }
-                   if (rank.isLower(Rank.SPECIES())){
+                   if (rank.isLowerThan(RankClass.Species)){
                        if (subgenus!=null){
                            String prefix = nvname.getGenusOrUninomial();
                            String name = nvname.getInfraGenericEpithet();
@@ -836,6 +833,30 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                            parent = linkParentChildNode(species, subspecies, classification, state);
                        }
                    }
+               }else{
+                   //handle cf. and aff. taxa
+                   String genusEpithet = null;
+                   if (nvname.getTitleCache().contains("cf.")){
+                       genusEpithet = nvname.getTitleCache().substring(0, nvname.getTitleCache().indexOf("cf."));
+                   } else if (nvname.getTitleCache().contains("aff.")){
+                       genusEpithet = nvname.getTitleCache().substring(0, nvname.getTitleCache().indexOf("aff."));
+                   }
+                   if (genusEpithet != null){
+                   genusEpithet = genusEpithet.trim();
+                   TaxonName taxonName = null;
+                   if (genusEpithet.contains(" ")){
+                       taxonName = getOrCreateTaxonName(genusEpithet, Rank.SPECIES(), preferredFlag, state, -1);
+                   }else{
+                       taxonName = getOrCreateTaxonName(genusEpithet, Rank.GENUS(), preferredFlag, state, -1);
+                   }
+                   genus = getOrCreateTaxonForName(taxonName, state);
+                    if (genus == null){
+                        logger.debug("The genus should not be null " + taxonName);
+                    }
+                    if (preferredFlag) {
+                        parent = linkParentChildNode(null, genus, classification, state);
+                    }
+                   }
                }
                if (preferredFlag && parent!=taxon ) {
                    linkParentChildNode(parent, taxon, classification, state);
@@ -852,9 +873,12 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             */
            protected Taxon linkParentChildNode(Taxon parent, Taxon child, Classification classification, STATE state) {
                TaxonNode node =null;
+               List<String> propertyPaths = new ArrayList<>();
+            propertyPaths.add("childNodes");
                if (parent != null) {
-                   parent = (Taxon) getTaxonService().find(parent.getUuid());
-                   child = (Taxon) getTaxonService().find(child.getUuid());
+
+                   parent = (Taxon) getTaxonService().load(parent.getUuid(), propertyPaths);
+                   child = (Taxon) getTaxonService().load(child.getUuid(), propertyPaths);
                    //here we do not have to check if the taxon nodes already exists
                    //this is done by classification.addParentChild()
                    //do not add child node if it already exists
@@ -906,8 +930,9 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    }
                }
                else{
-                   Set<TaxonBase> taxonAndSynonyms = taxonName.getTaxonBases();
-                   for (TaxonBase taxonBase : taxonAndSynonyms) {
+                   @SuppressWarnings("rawtypes")
+                    Set<TaxonBase> taxonAndSynonyms = taxonName.getTaxonBases();
+                   for (TaxonBase<?> taxonBase : taxonAndSynonyms) {
                        if(taxonBase.isInstanceOf(Synonym.class)){
                            Synonym synonym = HibernateProxyHelper.deproxy(taxonBase, Synonym.class);
                            Taxon acceptedTaxonOfSynonym = synonym.getAcceptedTaxon();
@@ -931,7 +956,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                return taxon;
                }
                return null;
-
            }
 
            private boolean hasTaxonNodeInClassification(Taxon taxon, Classification classification){
@@ -952,8 +976,8 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             * @param derivedUnitFacade : the current derivedunitfacade
             */
            protected void handleIdentifications(STATE state, DerivedUnitFacade derivedUnitFacade) {
-              SpecimenImportConfiguratorBase config = state.getConfig();
 
+               SpecimenImportConfiguratorBase<?,?,?> config = state.getConfig();
 
                String scientificName = "";
                boolean preferredFlag = false;
@@ -973,8 +997,10 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
 
                    String preferred = identification.getPreferred();
                    preferredFlag = false;
-                   if (preferred != null){
-                   if (preferred.equals("1") || preferred.toLowerCase().indexOf("true") != -1 || state.getDataHolder().getIdentificationList().size()==1) {
+                   if (preferred != null || state.getDataHolder().getIdentificationList().size()==1){
+                       if (state.getDataHolder().getIdentificationList().size()==1){
+                           preferredFlag = true;
+                       }else if (preferred != null && (preferred.equals("1") || preferred.toLowerCase().indexOf("true") != -1) ) {
                        preferredFlag = true;
                    }
 
@@ -990,7 +1016,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    TaxonName taxonName = getOrCreateTaxonName(scientificName, null, preferredFlag, state, i);
                    Taxon taxon = getOrCreateTaxonForName(taxonName, state);
                    addTaxonNode(taxon, state,preferredFlag);
-                   linkDeterminationEvent(state, taxon, preferredFlag, derivedUnitFacade, identification.getIdentifier(), identification.getDate());
+                   linkDeterminationEvent(state, taxon, preferredFlag, derivedUnitFacade, identification.getIdentifier(), identification.getDate(), identification.getModifier());
                }
            }
 
@@ -1008,14 +1034,14 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                if (!existsInClassification(taxon,state.getClassification(), state)){
                    if(config.isMoveNewTaxaToDefaultClassification()){
                        //check if node exists in default classification
-                       if (!existsInClassification(taxon, state.getDefaultClassification(), state)){
-                           addParentTaxon(taxon, state, preferredFlag, state.getDefaultClassification());
+                       if (!existsInClassification(taxon, state.getDefaultClassification(true), state)){
+                           addParentTaxon(taxon, state, preferredFlag, state.getDefaultClassification(true));
                        }
-                   }
-                   else {
+                   }else{
                        //add non-existing taxon to current classification
                        addParentTaxon(taxon, state, preferredFlag, state.getClassification());
                    }
+
                }
            }
 
@@ -1060,13 +1086,14 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
             * @param derivedFacade : the derived Unit Facade
             */
            @SuppressWarnings("rawtypes")
-        protected void linkDeterminationEvent(STATE state, Taxon taxon, boolean preferredFlag,  DerivedUnitFacade derivedFacade, String identifierStr, String dateStr) {
+        protected void linkDeterminationEvent(STATE state, Taxon taxon, boolean preferredFlag,  DerivedUnitFacade derivedFacade, String identifierStr, String dateStr, String modifier) {
                SpecimenImportConfiguratorBase config = state.getConfig();
                if (logger.isDebugEnabled()){
                    logger.info("start linkdetermination with taxon:" + taxon.getUuid()+", "+taxon);
                }
 
                DeterminationEvent determinationEvent = DeterminationEvent.NewInstance();
+               //determinationEvent.setTaxon(taxon);
                determinationEvent.setTaxonName(taxon.getName());
                determinationEvent.setPreferredFlag(preferredFlag);
 
@@ -1081,7 +1108,17 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                if (dateStr != null){
                    determinationEvent.setTimeperiod(TimePeriodParser.parseString(dateStr));
                }
-               state.getDerivedUnitBase().addDetermination(determinationEvent);
+               if (modifier != null){
+                   if (modifier.equals("cf.")){
+                       determinationEvent.setModifier(DefinedTerm.DETERMINATION_MODIFIER_CONFER());
+                   }else if (modifier.equals("aff.")){
+                       determinationEvent.setModifier(DefinedTerm.DETERMINATION_MODIFIER_AFFINIS());
+                   }
+               }
+               if (config.isAddDeterminations()) {
+                   state.getDerivedUnitBase().addDetermination(determinationEvent);
+               }
+
 
                if (logger.isDebugEnabled()){
                    logger.debug("NB TYPES INFO: "+ state.getDataHolder().getStatusList().size());
@@ -1096,16 +1133,17 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                        if(cdmAppController == null){
                            cdmAppController = this;
                        }
-                       specimenTypeDesignationstatus = (SpecimenTypeDesignationStatus) cdmAppController.getTermService().find(specimenTypeDesignationstatus.getUuid());
+                       specimenTypeDesignationstatus = HibernateProxyHelper.deproxy(cdmAppController.getTermService().find(specimenTypeDesignationstatus.getUuid()), SpecimenTypeDesignationStatus.class);
                        //Designation
                        TaxonName name = taxon.getName();
                        SpecimenTypeDesignation designation = SpecimenTypeDesignation.NewInstance();
 
                        designation.setTypeStatus(specimenTypeDesignationstatus);
                        designation.setTypeSpecimen(state.getDerivedUnitBase());
-                       name.addTypeDesignation(designation, true);
+                       name.addTypeDesignation(designation, false);
                    }
                }
+               save(state.getDerivedUnitBase(), state);
 
                for (String[] fullReference : state.getDataHolder().getReferenceList()) {
 
@@ -1113,7 +1151,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    String strReference=fullReference[0];
                    String citationDetail = fullReference[1];
                    String citationURL = fullReference[2];
-                   List<Reference> references = getReferenceService().listByTitle(Reference.class, "strReference", MatchMode.EXACT, null, null, null, null, null);
+                   List<Reference> references = getReferenceService().listByTitleWithRestrictions(Reference.class, "strReference", MatchMode.EXACT, null, null, null, null, null);
 
                    if (!references.isEmpty()){
                        Reference reference = null;
@@ -1133,7 +1171,7 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                }
                save(state.getDerivedUnitBase(), state);
 
-               if (config.isAddIndividualsAssociationsSuchAsSpecimenAndObservations() && preferredFlag) {
+               if (config.isAddIndividualsAssociations() && preferredFlag) {
                    //do not add IndividualsAssociation to non-preferred taxa
                    if (logger.isDebugEnabled()){
                        logger.debug("isDoCreateIndividualsAssociations");
@@ -1161,36 +1199,36 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
 
                TaxonDescription taxonDescription = null;
                Set<TaxonDescription> descriptions= taxon.getDescriptions();
-              if (!descriptions.isEmpty()){ taxonDescription = descriptions.iterator().next();}
-
-//                 for (TaxonDescription description : descriptions){
-//                     Set<IdentifiableSource> sources =  new HashSet<>();
-//                     sources.addAll(description.getTaxon().getSources());
-//                     sources.addAll(description.getSources());
-//                     for (IdentifiableSource source:sources){
-//                         if(state.getRef().equals(source.getCitation())) {
-//                             taxonDescription = description;
-//                         }
-//                     }
-//                 }
-             //  }
-               if (taxonDescription == null){
+               if (state.getIndividualsAssociationDescriptionPerTaxon(taxon.getUuid()) != null){
+                   taxonDescription = state.getIndividualsAssociationDescriptionPerTaxon(taxon.getUuid());
+               }
+              if (taxonDescription == null && !descriptions.isEmpty() && state.getConfig().isReuseExistingDescriptiveGroups()){
+                  for (TaxonDescription desc: descriptions){
+                      if (desc.getTypes().contains(DescriptionType.INDIVIDUALS_ASSOCIATION)){
+                          taxonDescription = desc;
+                          break;
+                      }
+                  }
+              }
+
+              if (taxonDescription == null){
                    taxonDescription = TaxonDescription.NewInstance(taxon, false);
+                   taxonDescription.setTypes(EnumSet.of(DescriptionType.INDIVIDUALS_ASSOCIATION));
                    if(sourceNotLinkedToElement(taxonDescription,state.getRef(),null)) {
                        taxonDescription.addSource(OriginalSourceType.Import, null, null, state.getRef(), null);
                    }
-                   state.setDescriptionGroup(taxonDescription);
+                   state.setIndividualsAssociationDescriptionPerTaxon(taxonDescription);
                    taxon.addDescription(taxonDescription);
                }
 
                //PREPARE REFERENCE QUESTIONS
 
-               Map<String,OriginalSourceBase<?>> sourceMap = new HashMap<String, OriginalSourceBase<?>>();
+               Map<String,OriginalSourceBase> sourceMap = new HashMap<>();
 
                List<IdentifiableSource> issTmp = new ArrayList<>();//getCommonService().list(IdentifiableSource.class, null, null, null, null);
                List<DescriptionElementSource> issTmp2 = new ArrayList<>();//getCommonService().list(DescriptionElementSource.class, null, null, null, null);
 
-               Set<OriginalSourceBase> osbSet = new HashSet<OriginalSourceBase>();
+               Set<OriginalSourceBase> osbSet = new HashSet<>();
                if(issTmp2!=null) {
                    osbSet.addAll(issTmp2);
                }
@@ -1201,119 +1239,33 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
 
                addToSourceMap(sourceMap, osbSet);
 
-//             if (((Abcd206ImportConfigurator) state.getConfig()).isInteractWithUser()){
-//                 List<OriginalSourceBase<?>> res = null;
-//                 if(!state.isDescriptionSourcesSet()){
-//                     res = sui.askForSource(sourceMap, "the description group ("+taxon+")",
-//                             "The current reference is "+state.getRef().getTitleCache(),getReferenceService(), state.getDataHolder().docSources);
-//                     state.setDescriptionRefs(res);
-//                     state.setDescriptionSourcesSet(true);
-//                 }
-//                 else{
-//                     res=state.getDescriptionRefs();
-//                 }
-//                 if(res !=null) {
-//                     for (OriginalSourceBase<?> sour:res){
-//                         if(sour.isInstanceOf(IdentifiableSource.class)){
-//                             try {
-//                                 if(sourceNotLinkedToElement(taxonDescription,sour)) {
-//                                     taxonDescription.addSource((IdentifiableSource)sour.clone());
-//                                 }
-//                             } catch (CloneNotSupportedException e) {
-//                                 logger.warn("no cloning?");
-//                             }
-//                         }else{
-//                             if(sourceNotLinkedToElement(taxonDescription,sour)) {
-//                                 taxonDescription.addSource(OriginalSourceType.Import,null, null, sour.getCitation(),sour.getCitationMicroReference());
-//                             }
-//                         }
-//                     }
-//                 }
-//             }
-//             else {
-                   if(sourceNotLinkedToElement(taxonDescription,state.getRef(),null)) {
-                       taxonDescription.addSource(OriginalSourceType.Import,null, null, state.getRef(), null);
-                   }
-//             }
-               state.setDescriptionGroup(taxonDescription);
+
+            if(sourceNotLinkedToElement(taxonDescription,state.getRef(),null)) {
+                taxonDescription.addSource(OriginalSourceType.Import,null, null, state.getRef(), null);
+            }
+
+               state.setIndividualsAssociationDescriptionPerTaxon(taxonDescription);
 
                IndividualsAssociation indAssociation = IndividualsAssociation.NewInstance();
                Feature feature = makeFeature(state.getDerivedUnitBase());
                indAssociation.setAssociatedSpecimenOrObservation(state.getDerivedUnitBase());
                indAssociation.setFeature(feature);
-//
-//             if (((Abcd206ImportConfigurator) state.getConfig()).isInteractWithUser()){
-//                 sourceMap = new HashMap<String, OriginalSourceBase<?>>();
-//
-//                 issTmp = getCommonService().list(IdentifiableSource.class, null, null, null, null);
-//                 issTmp2 = getCommonService().list(DescriptionElementSource.class, null, null, null, null);
-//
-//                 osbSet = new HashSet<OriginalSourceBase>();
-//                 if(issTmp2!=null) {
-//                     osbSet.addAll(issTmp2);
-//                 }
-//                 if(issTmp!=null) {
-//                     osbSet.addAll(issTmp);
-//                 }
-//
-//
-//                 addToSourceMap(sourceMap, osbSet);
-//
-//                 List<OriginalSourceBase<?>> sources =null;
-//                 if(!state.isAssociationSourcesSet()) {
-//                     sources = sui.askForSource(sourceMap,  "descriptive element (association) ",taxon.toString(),
-//                             getReferenceService(),state.getDataHolder().getDocSources());
-//                     state.setAssociationRefs(sources);
-//                     state.setAssociationSourcesSet(true);
-//                 }
-//                 else{
-//                     sources=state.getAssociationRefs();
-//                 }
-//                 if(sources !=null) {
-//                     for (OriginalSourceBase<?> source: sources) {
-//                         if(source !=null) {
-//                             if(source.isInstanceOf(DescriptionElementSource.class)){
-//                                 try {
-//                                     if(sourceNotLinkedToElement(indAssociation,source)) {
-//                                         indAssociation.addSource((DescriptionElementSource)source.clone());
-//                                     }
-//                                 } catch (CloneNotSupportedException e) {
-//                                     logger.warn("clone forbidden?");
-//                                 }
-//                             }else{
-//                                 if(sourceNotLinkedToElement(indAssociation,source)) {
-//                                     indAssociation.addSource(OriginalSourceType.Import,null, null, source.getCitation(),source.getCitationMicroReference());
-//                                 }
-//                                 try {
-//                                     if(sourceNotLinkedToElement(state.getDerivedUnitBase(), source)) {
-//                                         state.getDerivedUnitBase().addSource((IdentifiableSource) source.clone());
-//                                     }
-//                                 } catch (CloneNotSupportedException e) {
-//                                     // TODO Auto-generated catch block
-//                                     e.printStackTrace();
-//                                 }
-//                             }
-//
-//                         }
-//                     }
-//                 }
-//             }else {
-                   if(sourceNotLinkedToElement(indAssociation,state.getRef(),null)) {
-                       indAssociation.addSource(OriginalSourceType.Import,null, null, state.getRef(), null);
-                   }
-                   if(sourceNotLinkedToElement(state.getDerivedUnitBase(), state.getRef(),null)) {
-                       state.getDerivedUnitBase().addSource(OriginalSourceType.Import,null, null, state.getRef(), null);
-                   }
-                   for (Reference citation : determinationEvent.getReferences()) {
-                       if(sourceNotLinkedToElement(indAssociation,citation,null))
-                       {
-                           indAssociation.addSource(DescriptionElementSource.NewInstance(OriginalSourceType.Import, null, null, citation, null));
-                       }
-                       if(sourceNotLinkedToElement(state.getDerivedUnitBase(), state.getRef(),null)) {
-                           state.getDerivedUnitBase().addSource(OriginalSourceType.Import,null, null, state.getRef(), null);
-                       }
-                   }
-          //     }
+
+            if(sourceNotLinkedToElement(indAssociation,state.getImportReference(state.getActualAccessPoint()),null)) {
+                indAssociation.addSource(OriginalSourceType.Import,null, null, state.getImportReference(state.getActualAccessPoint()), null);
+            }
+            if(sourceNotLinkedToElement(state.getDerivedUnitBase(), state.getImportReference(state.getActualAccessPoint()),null)) {
+                state.getDerivedUnitBase().addSource(OriginalSourceType.Import,null, null, state.getImportReference(state.getActualAccessPoint()), null);
+            }
+            for (Reference citation : determinationEvent.getReferences()) {
+                if(sourceNotLinkedToElement(indAssociation,citation,null))
+                {
+                    indAssociation.addSource(DescriptionElementSource.NewInstance(OriginalSourceType.Import, null, null, citation, null));
+                }
+                if(sourceNotLinkedToElement(state.getDerivedUnitBase(), state.getImportReference(state.getActualAccessPoint()),null)) {
+                    state.getDerivedUnitBase().addSource(OriginalSourceType.Import,null, null, state.getImportReference(state.getActualAccessPoint()), null);
+                }
+            }
 
                taxonDescription.addElement(indAssociation);
 
@@ -1323,12 +1275,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                state.getReport().addIndividualAssociation(taxon, state.getDataHolder().getUnitID(), state.getDerivedUnitBase());
            }
 
-           /**
-            * @param derivedUnitBase2
-            * @param ref2
-            * @param object
-            * @return
-            */
            private boolean sourceNotLinkedToElement(DerivedUnit derivedUnitBase2, Reference b, String d) {
                Set<IdentifiableSource> linkedSources = derivedUnitBase2.getSources();
                for (IdentifiableSource is:linkedSources){
@@ -1349,7 +1295,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                        }
                    }catch(Exception e){}
 
-
                    try{
                        if (c==null && d==null) {
                            microMatch=true;
@@ -1365,13 +1310,13 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    if (microMatch && refMatch) {
                        return false;
                    }
-
-
                }
                return true;
            }
 
-           private <T extends OriginalSourceBase<?>> boolean  sourceNotLinkedToElement(ISourceable<T> sourcable, Reference reference, String microReference) {
+           private <T extends OriginalSourceBase> boolean  sourceNotLinkedToElement(
+                   ISourceable<T> sourcable, Reference reference, String microReference) {
+
                Set<T> linkedSources = sourcable.getSources();
                for (T is:linkedSources){
                    Reference unitReference = is.getCitation();
@@ -1418,8 +1363,6 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
            private Feature makeFeature(SpecimenOrObservationBase<?> unit) {
                SpecimenOrObservationType type = unit.getRecordBasis();
 
-
-
                if (type.isFeatureObservation()){
                    return Feature.OBSERVATION();
                }else if (type.isFeatureSpecimen()){
@@ -1429,20 +1372,15 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    //            return getFeature("Specimen or observation");
                }else{
                    String message = "Unhandled record basis '%s' for defining individuals association feature type. Use default.";
-                   logger.warn(String.format(message, type.getMessage()));
+                   logger.warn(String.format(message, type.getLabel()));
                    return Feature.OBSERVATION();
                    //            return getFeature("Specimen or observation");
 
                }
            }
 
-
-           /**
-            * @param sourceMap
-            * @param osbSet
-            */
-           protected void addToSourceMap(Map<String, OriginalSourceBase<?>> sourceMap, Set<OriginalSourceBase> osbSet) {
-               for( OriginalSourceBase<?> osb:osbSet) {
+           protected void addToSourceMap(Map<String, OriginalSourceBase> sourceMap, Set<OriginalSourceBase> osbSet) {
+               for( OriginalSourceBase osb:osbSet) {
                    if(osb.getCitation()!=null && osb.getCitationMicroReference() !=null  && !osb.getCitationMicroReference().isEmpty()) {
                        try{
                            sourceMap.put(osb.getCitation().getTitleCache()+ "---"+osb.getCitationMicroReference(),osb);
@@ -1454,6 +1392,4 @@ public abstract class SpecimenImportBase<CONFIG extends IImportConfigurator, STA
                    }
                }
            }
-
-
-}
+}
\ No newline at end of file