#4366 Transmissionengine aggregation of source references
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Wed, 29 Jun 2016 13:56:15 +0000 (15:56 +0200)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Wed, 29 Jun 2016 13:57:07 +0000 (15:57 +0200)
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/OriginalSourceBase.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/common/ReferencedEntityBase.java
cdmlib-model/src/main/java/eu/etaxonomy/cdm/model/description/DescriptionElementSource.java
cdmlib-services/src/main/java/eu/etaxonomy/cdm/api/service/description/TransmissionEngineDistribution.java
cdmlib-services/src/test/java/eu/etaxonomy/cdm/api/service/TransmissionEngineDistributionTest.java
cdmlib-services/src/test/resources/eu/etaxonomy/cdm/api/service/TransmissionEngineDistributionTest.xml

index 68ea146045bcbe102fffb651bbb35ea871b027d7..27921149bc511a74624e97d4d80bd7f2667e3feb 100644 (file)
@@ -150,4 +150,24 @@ public abstract class OriginalSourceBase<T extends ISourceable> extends Referenc
                }
        }
 
+//*********************************** EQUALS *********************************************************/
+
+       /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equalsByShallowCompare(ReferencedEntityBase other) {
+
+        if(!super.equalsByShallowCompare(other)) {
+            return false;
+        }
+        OriginalSourceBase<T> theOther = (OriginalSourceBase<T>)other;
+        if(!StringUtils.equals(this.getIdInSource(), theOther.getIdInSource())
+                || !StringUtils.equals(this.getIdNamespace(), theOther.getIdNamespace())) {
+            return false;
+        }
+
+        return true;
+    }
+
 }
\ No newline at end of file
index e08b2905c89c8e01f60ca9f1f0115f79b5147f4c..11b9a74c5e2250fcbba1957826514428ce4b35f0 100644 (file)
@@ -21,6 +21,7 @@ import javax.xml.bind.annotation.XmlRootElement;
 import javax.xml.bind.annotation.XmlSchemaType;
 import javax.xml.bind.annotation.XmlType;
 
+import org.apache.commons.lang.StringUtils;
 import org.apache.log4j.Logger;
 import org.hibernate.annotations.Cascade;
 import org.hibernate.annotations.CascadeType;
@@ -118,4 +119,28 @@ public abstract class ReferencedEntityBase extends AnnotatableEntity implements
                return result;
        }
 
+//*********************************** EQUALS *********************************************************/
+
+       /**
+        * Indicates whether some other object is "equal to" this one.
+        *
+        * Uses a content based compare strategy which avoids bean initialization. This is achieved by
+        * comparing the cdm entity ids.
+        *
+        * @param other
+        * @return
+        */
+       public boolean equalsByShallowCompare(ReferencedEntityBase other) {
+
+        if(this.getCitation().getId() != other.getCitation().getId()
+                || !StringUtils.equals(this.getCitationMicroReference(), other.getCitationMicroReference())
+                || !StringUtils.equals(this.getOriginalNameString(), other.getOriginalNameString())
+                        ){
+            return false;
+        }
+
+        return true;
+    }
+
+
 }
\ No newline at end of file
index 4bbba68bf5d52daafc9ab8686ff355dfd2b2a3ac..a201db9f1c140f9cdffcf3192eb3923bda918b5d 100644 (file)
@@ -25,6 +25,7 @@ import org.hibernate.envers.Audited;
 
 import eu.etaxonomy.cdm.model.common.OriginalSourceBase;
 import eu.etaxonomy.cdm.model.common.OriginalSourceType;
+import eu.etaxonomy.cdm.model.common.ReferencedEntityBase;
 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
 import eu.etaxonomy.cdm.model.reference.Reference;
 
@@ -163,6 +164,29 @@ public class DescriptionElementSource extends OriginalSourceBase<DescriptionElem
                return result;
        }
 
+//*********************************** EQUALS *********************************************************/
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public boolean equalsByShallowCompare(ReferencedEntityBase other) {
+
+           if(!super.equalsByShallowCompare(other)) {
+               return false;
+           }
+
+           int a = -1;
+           int b = -1;
+           if(this.getNameUsedInSource() != null) {
+               a = this.getNameUsedInSource().getId();
+           }
+           DescriptionElementSource otherDescriptionElementSource = (DescriptionElementSource)other;
+        if(otherDescriptionElementSource.getNameUsedInSource() != null) {
+            b = otherDescriptionElementSource.getNameUsedInSource().getId();
+        }
+           return a == b;
+       }
 
 
 }
index 30c9cad29cafdb4108aa84337cbbbc2a7f16e8cc..03199a5e9821425fab64c069ff9346038d65c870 100644 (file)
@@ -19,7 +19,6 @@ import java.util.Map;
 import java.util.Set;
 import java.util.UUID;
 
-import org.apache.log4j.Level;
 import org.apache.log4j.Logger;
 import org.hibernate.FlushMode;
 import org.hibernate.HibernateException;
@@ -244,9 +243,11 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
      *
      * @param a
      * @param b
+     * @param sourcesForWinnerB
+     *  In the case when <code>b</code> is preferred over <code>a</code> these Set of sources will be added to the sources of <code>b</code>
      * @return
      */
-    private StatusAndSources choosePreferred(StatusAndSources a, StatusAndSources b){
+    private StatusAndSources choosePreferred(StatusAndSources a, StatusAndSources b, Set<DescriptionElementSource> sourcesForWinnerB){
 
         if (statusPriorityMap == null) {
             initializeStatusPriorityMap();
@@ -268,9 +269,12 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
             return a;
         }
         if(statusPriorityMap.get(a.status) < statusPriorityMap.get(b.status)){
+            if(sourcesForWinnerB != null) {
+                b.addSources(sourcesForWinnerB);
+            }
             return b;
         } else if (statusPriorityMap.get(a.status) == statusPriorityMap.get(b.status)){
-            a.sources.addAll(b.sources);
+            a.addSources(b.sources);
             return a;
         } else {
             return a;
@@ -335,7 +339,7 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
 
 
         // only for debugging:
-        logger.setLevel(Level.DEBUG); // TRACE will slow down a lot since it forces loading all term representations
+        //logger.setLevel(Level.TRACE); // TRACE will slow down a lot since it forces loading all term representations
         //Logger.getLogger("org.hibernate.SQL").setLevel(Level.DEBUG);
 
         logger.info("Hibernate JDBC Batch size: "
@@ -481,7 +485,7 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
                                     continue;
                                 }
                                 StatusAndSources subStatusAndSources = new StatusAndSources(status, distribution.getSources());
-                                accumulatedStatusAndSources = choosePreferred(accumulatedStatusAndSources, subStatusAndSources);
+                                accumulatedStatusAndSources = choosePreferred(accumulatedStatusAndSources, subStatusAndSources, null);
                             }
                         }
                     } // next sub area
@@ -491,6 +495,7 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
                         }
                         // store new distribution element for superArea in taxon description
                         Distribution newDistribitionElement = Distribution.NewInstance(superArea, accumulatedStatusAndSources.status);
+                        newDistribitionElement.getSources().addAll(accumulatedStatusAndSources.sources);
                         newDistribitionElement.addMarker(Marker.NewInstance(MarkerType.COMPUTED(), true));
                         description.addElement(newDistribitionElement);
                     }
@@ -520,7 +525,7 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
     }
 
    /**
-    * Step 2: Accumulate by ranks staring from lower rank to upper rank, the status of all children
+    * Step 2: Accumulate by ranks starting from lower rank to upper rank, the status of all children
     * are accumulated on each rank starting from lower rank to upper rank.
     * <ul>
     * <li>aggregate distribution of included taxa of the next lower rank for any rank level starting from the lower rank (e.g. sub species)
@@ -566,7 +571,7 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
             while (taxonIdIterator.hasNext()) {
 
                 if(txStatus == null) {
-                    // transaction has been comitted at the end of this batch, start a new one
+                    // transaction has been committed at the end of this batch, start a new one
                     txStatus = startTransaction(false);
                 }
 
@@ -624,17 +629,22 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
                                 }
 
                                 StatusAndSources subStatusAndSources = new StatusAndSources(status, distribution.getSources());
-                                accumulatedStatusMap.put(area, choosePreferred(accumulatedStatusMap.get(area), subStatusAndSources));
+                                accumulatedStatusMap.put(area, choosePreferred(accumulatedStatusMap.get(area), subStatusAndSources, null));
                              }
                         }
 
                         if(accumulatedStatusMap.size() > 0) {
                             TaxonDescription description = findComputedDescription(taxon, doClearDescriptions);
                             for (NamedArea area : accumulatedStatusMap.keySet()) {
-                                // store new distribution element in new Description
-                                Distribution newDistribitionElement = Distribution.NewInstance(area, accumulatedStatusMap.get(area).status);
-                                newDistribitionElement.addMarker(Marker.NewInstance(MarkerType.COMPUTED(), true));
-                                description.addElement(newDistribitionElement);
+                                Distribution distribition = findDistribution(description, area, accumulatedStatusMap.get(area).status);
+                                if(distribition == null) {
+                                    // create a new distribution element
+                                    distribition = Distribution.NewInstance(area, accumulatedStatusMap.get(area).status);
+                                    distribition.addMarker(Marker.NewInstance(MarkerType.COMPUTED(), true));
+                                }
+                                addSourcesDeduplicated(distribition.getSources(), accumulatedStatusMap.get(area).sources);
+
+                                description.addElement(distribition);
                             }
                             taxonService.saveOrUpdate(taxon);
                             descriptionService.saveOrUpdate(description);
@@ -670,6 +680,25 @@ public class TransmissionEngineDistribution { //TODO extends IoBase?
         subMonitor.done();
     }
 
+/**
+ * @param description
+ * @param area
+ * @param status
+ * @return
+ */
+private Distribution findDistribution(TaxonDescription description, NamedArea area, PresenceAbsenceTerm status) {
+    for(DescriptionElementBase item : description.getElements()) {
+        if(!(item instanceof Distribution)) {
+            continue;
+        }
+        Distribution distribution = ((Distribution)item);
+        if(distribution.getArea().equals(area) && distribution.getStatus().equals(status)) {
+            return distribution;
+        }
+    }
+    return null;
+}
+
 /**
  * @param lowerRank
  * @param upperRank
@@ -927,6 +956,26 @@ private List<Rank> rankInterval(Rank lowerRank, Rank upperRank) {
         commitTransaction(txStatus);
     }
 
+    public static void addSourcesDeduplicated(Set<DescriptionElementSource> target, Set<DescriptionElementSource> sources) {
+        for(DescriptionElementSource source : sources) {
+            boolean contained = false;
+            for(DescriptionElementSource existingSource: target) {
+                if(existingSource.equalsByShallowCompare(source)) {
+                    contained = true;
+                    break;
+                }
+            }
+            if(!contained) {
+                try {
+                    target.add((DescriptionElementSource)source.clone());
+                } catch (CloneNotSupportedException e) {
+                    // should never happen
+                    throw new RuntimeException(e);
+                }
+            }
+        }
+    }
+
     public enum AggregationMode {
         byAreas,
         byRanks,
@@ -936,13 +985,21 @@ private List<Rank> rankInterval(Rank lowerRank, Rank upperRank) {
 
     private class StatusAndSources {
 
-        PresenceAbsenceTerm status;
+        private final PresenceAbsenceTerm status;
 
-        Set<DescriptionElementSource> sources = new HashSet<>();
+        private final Set<DescriptionElementSource> sources = new HashSet<>();
 
         public StatusAndSources(PresenceAbsenceTerm status, Set<DescriptionElementSource> sources) {
             this.status = status;
-            this.sources = sources;
+            addSourcesDeduplicated(this.sources, sources);
         }
+
+        /**
+         * @param sources
+         */
+        public void addSources(Set<DescriptionElementSource> sources) {
+            addSourcesDeduplicated(this.sources, sources);
+        }
+
     }
 }
index 27df05abd30d8af572b4b8bb188eb1aebc9411d0..c3c341938c9e2e2d1a768447745537a5080f9c24 100644 (file)
@@ -12,9 +12,13 @@ package eu.etaxonomy.cdm.api.service;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
 
 import java.io.FileNotFoundException;
 import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.UUID;
@@ -53,7 +57,6 @@ import eu.etaxonomy.cdm.test.unitils.CleanSweepInsertLoadStrategy;
  */
 public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrationTest {
 
-    @SuppressWarnings("unused")
     private static Logger logger = Logger.getLogger(TransmissionEngineDistributionTest.class);
 
     private static final UUID T_LAPSANA_UUID = UUID.fromString("f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8");
@@ -105,6 +108,9 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
 
     private Classification classification;
 
+    private Reference book_a = null;
+    private Reference book_b = null;
+
 
     @Before
     public void setUp() {
@@ -124,6 +130,11 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
         yug_ma = termService.getAreaByTdwgAbbreviation("YUG-MA");
         yug_mn = termService.getAreaByTdwgAbbreviation("YUG-MN");
 
+        book_a = ReferenceFactory.newBook();
+        book_a.setTitle("book_a");
+        book_b = ReferenceFactory.newBook();
+        book_b.setTitle("book_a");
+
         engine.updatePriorities();
     }
 
@@ -146,7 +157,7 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
 
         addDistributions(
                 T_LAPSANA_COMMUNIS_ALPINA_UUID,
-                new Distribution[] {
+                Arrays.asList(new Distribution[] {
                         // should succeed during area aggregation be ignored by rank aggregation
                         // => yug will get status ENDEMIC_FOR_THE_RELEVANT_AREA
                         //    but only for LAPSANA_COMMUNIS_ALPINA
@@ -154,7 +165,7 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
                         // should be ignored by area aggregation
                         // => LAPSANA_COMMUNIS will wave distribution with yug_ko and INTRODUCED_FORMERLY_INTRODUCED
                         Distribution.NewInstance(yug_ko, PresenceAbsenceTerm.INTRODUCED_FORMERLY_INTRODUCED()),
-               }
+               })
             );
 
         engine.accumulate(AggregationMode.byAreasAndRanks, superAreas, lowerRank, upperRank, null, null);
@@ -186,31 +197,16 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
     })
     public void testArea_area() {
 
-        Distribution[] distributions = new Distribution[4];
-
-        Reference book_LCA_yug_mn = ReferenceFactory.newBook();
-        book_LCA_yug_mn.setTitle("LCA_yug_mn");
-        DescriptionElementSource.NewPrimarySourceInstance(book_LCA_yug_mn, "1");
-        distributions[0] = Distribution.NewInstance(yug_mn, PresenceAbsenceTerm.CULTIVATED());
+        Set<Distribution> distributions_LCA = new HashSet<>();
 
-        Reference book_LCA_yug_ko = ReferenceFactory.newBook();
-        book_LCA_yug_mn.setTitle("LCA_yug_ko");
-        DescriptionElementSource.NewPrimarySourceInstance(book_LCA_yug_ko, "2");
-        distributions[1] = Distribution.NewInstance(yug_ko, PresenceAbsenceTerm.NATIVE()); // NATIVE should succeed
-
-        Reference book_LCA_yug_bh = ReferenceFactory.newBook();
-        book_LCA_yug_mn.setTitle("LCA_yug_bh");
-        DescriptionElementSource.NewPrimarySourceInstance(book_LCA_yug_bh, "3");
-        distributions[2] = Distribution.NewInstance(yug_bh, PresenceAbsenceTerm.INTRODUCED());
-
-        Reference book_LCA_yug_ma = ReferenceFactory.newBook();
-        book_LCA_yug_mn.setTitle("LCA_yug_ma");
-        DescriptionElementSource.NewPrimarySourceInstance(book_LCA_yug_ma, "4");
-        distributions[3] = Distribution.NewInstance(yug_ma, PresenceAbsenceTerm.NATIVE()); // NATIVE should succeed
+        distributions_LCA.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "1"));
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "2")); // NATIVE should succeed
+        distributions_LCA.add(newDistribution(book_a, yug_bh, PresenceAbsenceTerm.INTRODUCED(), "3"));
+        distributions_LCA.add(newDistribution(book_a, yug_ma, PresenceAbsenceTerm.NATIVE(), "4")); // NATIVE should succeed
 
         addDistributions(
                 T_LAPSANA_COMMUNIS_ALPINA_UUID,
-                distributions
+                distributions_LCA
             );
 
         Taxon lapsana_communis_alpina  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_ALPINA_UUID);
@@ -225,45 +221,53 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
         for (TaxonDescription description : lapsana_communis_alpina.getDescriptions()) {
             if(description.hasMarker(MarkerType.COMPUTED(), true)) {
                 assertNull("only one computed Distribution should exists", accumulatedDistribution);
-                assertEquals("the computed Decription should have only one element", 1, description.getElements().size());
+                assertEquals("the computed Decsription should have only one element", 1, description.getElements().size());
                 accumulatedDistribution = (Distribution) description.getElements().iterator().next();
                 assertEquals("Expecting area to be YUG", yug, accumulatedDistribution.getArea());
                 assertEquals("Expecting status to be NATIVE", PresenceAbsenceTerm.NATIVE().getLabel(), accumulatedDistribution.getStatus().getLabel());
             }
         }
         assertNotNull("The area YUG should have been found", accumulatedDistribution);
-//        assertEquals("Expecting two source references", accumulatedDistribution.getSources().size());
-//        assertTrue(accumulatedDistribution.getSources().contains(book_LCA_yug_ko));
-//        assertTrue(accumulatedDistribution.getSources().contains(book_LCA_yug_ma));
+        assertEquals("Expecting two source references", 2, accumulatedDistribution.getSources().size());
+        Iterator<DescriptionElementSource> sourceIt = accumulatedDistribution.getSources().iterator();
+        // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
+        assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
+        assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
     }
 
     @Test
     @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
-    public void testArea_rank_and_area() {
+    public void testArea_rank_and_area_1() {
+
+        Set<Distribution> distributions_LCA = new HashSet<>();
+        distributions_LCA.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "1"));
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "2")); // NATIVE should succeed
 
         addDistributions(
                 T_LAPSANA_COMMUNIS_ALPINA_UUID,
-                new Distribution[] {
-                        Distribution.NewInstance(yug_mn, PresenceAbsenceTerm.CULTIVATED()),
-                        Distribution.NewInstance(yug_ko, PresenceAbsenceTerm.NATIVE()), // should succeed
-               }
+                distributions_LCA
             );
+
+        Set<Distribution> distributions_LC = new HashSet<>();
+        distributions_LC.add(newDistribution(book_a, yug_mn, PresenceAbsenceTerm.CULTIVATED(), "3"));
+        distributions_LC.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "4")); // NATIVE should succeed
+
+        commitAndStartNewTransaction(null);
+
         addDistributions(
                 T_LAPSANA_COMMUNIS_UUID,
-                new Distribution[] {
-                        Distribution.NewInstance(yug_mn, PresenceAbsenceTerm.INTRODUCED_UNCERTAIN_DEGREE_OF_NATURALISATION()),
-                        Distribution.NewInstance(yug_ko, PresenceAbsenceTerm.CULTIVATED()),
-               }
+                distributions_LC
             );
 
         engine.accumulate(AggregationMode.byAreasAndRanks, superAreas, lowerRank, upperRank, null, null);
 
         Taxon lapsana_communis  = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
-        assertEquals(2, lapsana_communis.getDescriptions().size());
+        assertEquals("Lapsana communis alpina must only have 2 Descriptions", 2, lapsana_communis.getDescriptions().size());
 
         Taxon lapsana = (Taxon) taxonService.load(T_LAPSANA_UUID);
-        assertEquals(1, lapsana.getDescriptions().size());
+        assertEquals("Lapsana communis must only have 1 Description", 1, lapsana.getDescriptions().size());
         TaxonDescription description = lapsana.getDescriptions().iterator().next();
+        assertTrue(description.hasMarker(MarkerType.COMPUTED(), true));
         assertEquals(3, description.getElements().size());
         int numExpectedFound = 0;
         for (DescriptionElementBase element : description.getElements()){
@@ -271,25 +275,209 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
             if(distribution.getArea().equals(yug)){
                 numExpectedFound++;
                 assertEquals("aggregated status of area YUG is wrong", PresenceAbsenceTerm.NATIVE().getLabel(), distribution.getStatus().getLabel());
+                assertEquals(2, distribution.getSources().size());
+                Iterator<DescriptionElementSource> sourceIt = distribution.getSources().iterator();
+                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
+                assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
+                assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
             }
             if(distribution.getArea().equals(yug_mn)){
                 numExpectedFound++;
                 assertEquals("aggregated status of area YUG-MN is wrong", PresenceAbsenceTerm.CULTIVATED().getLabel(), distribution.getStatus().getLabel());
+                assertEquals(2, distribution.getSources().size());
+                Iterator<DescriptionElementSource> sourceIt = distribution.getSources().iterator();
+                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
+                assertTrue(" 1  3 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
+                assertTrue(" 1  3 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
             }
             if(distribution.getArea().equals(yug_ko)){
                 numExpectedFound++;
                 assertEquals("aggregated status of area YUG-KO wrong", PresenceAbsenceTerm.NATIVE().getLabel(), distribution.getStatus().getLabel());
+                assertEquals(2, distribution.getSources().size());
+                Iterator<DescriptionElementSource> sourceIt = distribution.getSources().iterator();
+                // should contain source_LCA_yug_ma and source_LCA_yug_ko, testing the microreference which is unique in the tests
+                assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
+                assertTrue(" 2  4 ".contains(" " + sourceIt.next().getCitationMicroReference() + " "));
             }
         }
         assertEquals("All three expected areas should have been found before", numExpectedFound, 3);
     }
 
+    /**
+     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to check the
+     * suppression of duplicates.
+     *
+     * This test relies on {@link #testArea_rank_and_area_1()}
+     * an makes assertions only on the alternative source references
+     */
+    @Test
+    @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class)
+    public void testArea_rank_and_area_2() {
+
+        Set<Distribution> distributions_LCA = new HashSet<Distribution>();
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
+        distributions_LCA.add(newDistribution(book_b, yug_ko, PresenceAbsenceTerm.NATIVE(), "2"));
+
+        addDistributions(
+                T_LAPSANA_COMMUNIS_ALPINA_UUID,
+                distributions_LCA
+            );
+
+
+        engine.accumulate(AggregationMode.byAreasAndRanks, superAreas, lowerRank, upperRank, null, null);
+
+        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
+        int computedDescriptionsCnt = 0;
+        for(TaxonDescription description : lapsana_communis.getDescriptions()) {
+            if(description.hasMarker(MarkerType.COMPUTED(), true)) {
+                computedDescriptionsCnt++;
+                assertEquals(2, description.getElements().size()); // yug, yug_ko
+                for(DescriptionElementBase distribution : description.getElements()) {
+                    logger.debug(((Distribution)distribution).getArea() + " " + sourcesToString(distribution));
+                    if(((Distribution)distribution).getArea().equals(yug_ko)){
+                        assertEquals(2, distribution.getSources().size());
+                    }
+                    if(((Distribution)distribution).getArea().equals(yug)){
+                        assertEquals(2, distribution.getSources().size());
+                    }
+                }
+            }
+        }
+        assertEquals(1, computedDescriptionsCnt);
+    }
+
+
+    /**
+     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to check the
+     * suppression of duplicates.
+     *
+     * This test relies on {@link #testArea_rank_and_area_1()}
+     * an makes assertions only on the alternative source references
+     */
+    @Test
+    @DataSets({
+        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
+        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
+        @DataSet(value="TransmissionEngineDistributionTest.xml"),
+    })
+    public void testArea_rank_and_area_3() {
+
+        Set<Distribution> distributions_LCA = new HashSet<Distribution>();
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "3"));
+
+        addDistributions(
+                T_LAPSANA_COMMUNIS_ALPINA_UUID,
+                distributions_LCA
+            );
+
+        Set<Distribution> distributions_LC = new HashSet<>();
+        distributions_LC.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
+        distributions_LC.add(newDistribution(book_b, yug_ko, PresenceAbsenceTerm.NATIVE(), "2"));
+
+        commitAndStartNewTransaction(null);
+
+        addDistributions(
+                T_LAPSANA_COMMUNIS_UUID,
+                distributions_LC
+            );
+
+        engine.accumulate(AggregationMode.byAreasAndRanks, superAreas, lowerRank, upperRank, null, null);
+
+        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
+        int computedDescriptionsCnt = 0;
+        for(TaxonDescription description : lapsana_communis.getDescriptions()) {
+            if(description.hasMarker(MarkerType.COMPUTED(), true)) {
+                computedDescriptionsCnt++;
+                assertEquals(2, description.getElements().size());
+                for(DescriptionElementBase distribution : description.getElements()) {
+                    logger.debug(((Distribution)distribution).getArea() + " " + sourcesToString(distribution));
+                    if(((Distribution)distribution).getArea().equals(yug_ko)){
+                        assertEquals(2, distribution.getSources().size());
+                    }
+                    if(((Distribution)distribution).getArea().equals(yug)){
+                        assertEquals(3, distribution.getSources().size());
+                    }
+                }
+            }
+        }
+        assertEquals(1, computedDescriptionsCnt);
+    }
+
+    /**
+     * Variant of {@link #testArea_rank_and_area_1()} with alternate source references to
+     * check the handling of the case where the target taxon already has the distribution which is the
+     * result of the aggregation (see http://dev.e-taxonomy.eu/trac/ticket/4366#comment:12)
+     *
+     * This test relies on {@link #testArea_rank_and_area_1()}
+     * an makes assertions only on the alternative source references
+     */
+    @Test
+    @DataSets({
+        @DataSet(loadStrategy=CleanSweepInsertLoadStrategy.class, value="/eu/etaxonomy/cdm/database/ClearDB_with_Terms_DataSet.xml"),
+        @DataSet(value="/eu/etaxonomy/cdm/database/TermsDataSet-with_auditing_info.xml"),
+        @DataSet(value="TransmissionEngineDistributionTest.xml"),
+    })
+    public void testArea_rank_and_area_4() {
+
+        Set<Distribution> distributions_LCA = new HashSet<>();
+        distributions_LCA.add(newDistribution(book_a, yug_ko, PresenceAbsenceTerm.NATIVE(), "1"));
+
+        addDistributions(
+                T_LAPSANA_COMMUNIS_ALPINA_UUID,
+                distributions_LCA
+            );
+
+        Set<Distribution> distributions_LC = new HashSet<>();
+        distributions_LC.add(newDistribution(book_a, yug, PresenceAbsenceTerm.NATIVE(), "2")); //  should succeed
+
+        commitAndStartNewTransaction(null);
+
+        addDistributions(
+                T_LAPSANA_COMMUNIS_UUID,
+                distributions_LC
+            );
+
+        engine.accumulate(AggregationMode.byAreasAndRanks, superAreas, lowerRank, upperRank, null, null);
+
+        Taxon lapsana_communis = (Taxon) taxonService.load(T_LAPSANA_COMMUNIS_UUID);
+        int computedDescriptionsCnt = 0;
+        for(TaxonDescription description : lapsana_communis.getDescriptions()) {
+            if(description.hasMarker(MarkerType.COMPUTED(), true)) {
+                computedDescriptionsCnt++;
+                assertEquals(2, description.getElements().size());
+                Distribution distribution = (Distribution)description.getElements().iterator().next();
+                if(distribution.getArea().equals(yug_ko)){
+                    assertEquals(2, distribution.getSources().size());
+                    DescriptionElementSource source = distribution.getSources().iterator().next();
+                    assertEquals("2", source.getCitationMicroReference());
+                }
+            }
+        }
+        assertEquals(1, computedDescriptionsCnt);
+    }
+
+    /**
+     * @param referenceTitle
+     * @param area
+     * @param status
+     * @param microCitation
+     * @return
+     */
+    private Distribution newDistribution(Reference reference, NamedArea area, PresenceAbsenceTerm status,
+            String microCitation) {
+        DescriptionElementSource source = DescriptionElementSource.NewPrimarySourceInstance(reference, microCitation);
+        Distribution distribution = Distribution.NewInstance(area, status);
+        distribution.getSources().add(source);
+        return distribution;
+    }
+
     /**
      * creates a new description for the taxon identified by the UUIDs
      * @param taxonUuid
      * @param distributions
      */
-    private void addDistributions(UUID taxonUuid, Distribution[] distributions) {
+    private void addDistributions(UUID taxonUuid, Collection<Distribution> distributions) {
         Taxon taxon = (Taxon) taxonService.load(taxonUuid);
         if(taxon == null) {
             throw new NullPointerException("No taxon found for " + taxonUuid);
@@ -304,6 +492,14 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
         commitAndStartNewTransaction(null);
     }
 
+    private String sourcesToString(DescriptionElementBase deb) {
+        StringBuffer out = new StringBuffer();
+        for ( DescriptionElementSource source : deb.getSources()) {
+            out.append(source.getCitation().getTitle() + " : " + source.getCitationMicroReference() + ", ");
+        }
+        return out.toString();
+    }
+
 
     //@Test //  uncomment to create test data file//
     @Override
@@ -393,6 +589,7 @@ public class TransmissionEngineDistributionTest extends CdmTransactionalIntegrat
                 "REFERENCE", "DESCRIPTIONELEMENTBASE", "DESCRIPTIONBASE",
                 "AGENTBASE", "CLASSIFICATION",  "TAXONNODE",
                 "HOMOTYPICALGROUP", "LANGUAGESTRING",
+                "HIBERNATE_SEQUENCES"
          });
 
     }
index f6296a68950b316bb7a76ee03d58d4572b84faf5..afa7deece6e92ec0e4a7aa08c6fbf60107fb5f9a 100644 (file)
@@ -1,28 +1,41 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <dataset>
-  <TAXONBASE DTYPE="Taxon" ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Lapsana sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONBASE DTYPE="Taxon" ID="5001" CREATED="2016-06-22 15:19:53.0" UUID="2a5ceebb-4830-4524-b330-78461bf8cb6b" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5001" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONBASE DTYPE="Taxon" ID="5002" CREATED="2016-06-22 15:19:53.0" UUID="441a3c40-0c84-11de-8c30-0800200c9a66" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. communis sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5002" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONBASE DTYPE="Taxon" ID="5003" CREATED="2016-06-22 15:19:53.0" UUID="e4acf200-63b6-11dd-ad8b-0800200c9a66" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. adenophora sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5003" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONBASE DTYPE="Taxon" ID="5004" CREATED="2016-06-22 15:19:53.0" UUID="596b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. alpina sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5004" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="a5daa719-3552-4829-86e1-f4d4ec14d336" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="Lapsana" APPENDEDPHRASE="[null]" FULLTITLECACHE="Lapsana" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5000" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="774" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5001" CREATED="2016-06-22 15:19:53.0" UUID="db6e0607-58f0-448c-849a-26441563689d" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5001" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="765" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5002" CREATED="2016-06-22 15:19:53.0" UUID="7f122843-b7db-45ce-abe4-81dd1cd37f19" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. communis" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. communis" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5002" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5003" CREATED="2016-06-22 15:19:53.0" UUID="b6a9cdb3-69b8-44ae-b2c9-f0d2360d7083" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. adenophora" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. adenophora" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5003" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
-  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5004" CREATED="2016-06-22 15:19:53.0" UUID="62ca2164-cbd2-4e0d-b99c-6b6cf258c622" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. alpina" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. alpina" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5004" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
-  <REFERENCE DTYPE="[null]" ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="fa41cb1f-1404-41e9-a777-f4b01eaa9ae0" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="Sp.Pl." DATEPUBLISHED_END="[null]" DATEPUBLISHED_FREETEXT="[null]" DATEPUBLISHED_START="[null]" EDITION="[null]" EDITOR="[null]" ISBN="[null]" ISSN="[null]" DOI="[null]" NOMENCLATURALLYRELEVANT="false" ORGANIZATION="[null]" PAGES="[null]" PARSINGPROBLEM="0" PLACEPUBLISHED="[null]" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PUBLISHER="[null]" REFERENCEABSTRACT="[null]" SERIESPART="[null]" TITLE="[null]" ABBREVTITLE="[null]" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="DB" URI="[null]" VOLUME="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" AUTHORSHIP_ID="[null]" INREFERENCE_ID="[null]" INSTITUTION_ID="[null]" SCHOOL_ID="[null]"/>
-  <REFERENCE DTYPE="[null]" ID="5001" CREATED="2016-06-22 15:19:53.0" UUID="ea67d687-b338-4877-8852-b81c4f57f774" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Reference [type=Book, id= 0, uuid=ea67d687-b338-4877-8852-b81c4f57f774]" DATEPUBLISHED_END="[null]" DATEPUBLISHED_FREETEXT="[null]" DATEPUBLISHED_START="[null]" EDITION="[null]" EDITOR="[null]" ISBN="[null]" ISSN="[null]" DOI="[null]" NOMENCLATURALLYRELEVANT="false" ORGANIZATION="[null]" PAGES="[null]" PARSINGPROBLEM="0" PLACEPUBLISHED="[null]" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PUBLISHER="[null]" REFERENCEABSTRACT="[null]" SERIESPART="[null]" TITLE="[null]" ABBREVTITLE="[null]" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="BK" URI="[null]" VOLUME="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" AUTHORSHIP_ID="[null]" INREFERENCE_ID="[null]" INSTITUTION_ID="[null]" SCHOOL_ID="[null]"/>
-  <CLASSIFICATION ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="4b266053-a841-4980-b548-3f21d8d7d712" UPDATED="2016-06-22 15:19:53.097" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="TestClassification" MICROREFERENCE="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_FREETEXT="[null]" TIMEPERIOD_END="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" REFERENCE_ID="[null]" ROOTNODE_ID="5000"/>
-  <TAXONNODE ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="fcdb08a7-3a53-4126-ba5c-532188cc0d65" UPDATED="2016-06-22 15:19:53.098" SORTINDEX="-1" TREEINDEX="#t5000#5000#" COUNTCHILDREN="1" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="[null]" REFERENCEFORPARENTCHILDRELATION_ID="[null]" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="[null]"/>
-  <TAXONNODE ID="5001" CREATED="2016-06-22 15:19:53.0" UUID="ae4704b7-0e33-421f-b8a2-2a7e17b9fde1" UPDATED="[null]" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#" COUNTCHILDREN="1" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5000" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5000"/>
-  <TAXONNODE ID="5002" CREATED="2016-06-22 15:19:53.0" UUID="68a9e8ac-3ae1-4d83-96d3-63b056e42de1" UPDATED="2016-06-22 15:19:53.098" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#5002#" COUNTCHILDREN="3" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5001" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5001"/>
-  <TAXONNODE ID="5003" CREATED="2016-06-22 15:19:53.0" UUID="88eed5b8-0a41-4b4a-8ded-6a6a0d8dd673" UPDATED="[null]" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#5002#5003#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5002"/>
-  <TAXONNODE ID="5004" CREATED="2016-06-22 15:19:53.0" UUID="c6df76dc-3dcf-4034-bf86-9f4a6c23b870" UPDATED="2016-06-22 15:19:53.098" SORTINDEX="1" TREEINDEX="#t5000#5000#5001#5002#5004#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5003"/>
-  <TAXONNODE ID="5005" CREATED="2016-06-22 15:19:53.0" UUID="c39e7750-9d0f-4901-92a4-6043ef7ff524" UPDATED="2016-06-22 15:19:53.099" SORTINDEX="2" TREEINDEX="#t5000#5000#5001#5002#5005#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5004"/>
-  <HOMOTYPICALGROUP ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="8063b8c6-73a3-4f20-8109-93ffe6d101da" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
-  <HOMOTYPICALGROUP ID="5001" CREATED="2016-06-22 15:19:53.0" UUID="5c066a04-b5ae-4537-bc47-5803569daaa4" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
-  <HOMOTYPICALGROUP ID="5002" CREATED="2016-06-22 15:19:53.0" UUID="13527861-46cc-48bb-aa30-9c72b956e890" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
-  <HOMOTYPICALGROUP ID="5003" CREATED="2016-06-22 15:19:53.0" UUID="1f75856b-e970-4432-a86e-b2747ad8e16e" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
-  <HOMOTYPICALGROUP ID="5004" CREATED="2016-06-22 15:19:53.0" UUID="2da2c603-923f-4433-a9c3-66196da96f68" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
-  <LANGUAGESTRING ID="5000" CREATED="2016-06-22 15:19:53.0" UUID="c49ddee1-fe7b-48f1-8f81-71f0b1584e71" UPDATED="[null]" TEXT="TestClassification" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LANGUAGE_ID="406"/>
+  <TAXONBASE DTYPE="Taxon" ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="f65d47bd-4f49-4ab1-bc4a-bc4551eaa1a8" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Lapsana sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONBASE DTYPE="Taxon" ID="5001" CREATED="2016-06-27 14:26:11.0" UUID="2a5ceebb-4830-4524-b330-78461bf8cb6b" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5001" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONBASE DTYPE="Taxon" ID="5002" CREATED="2016-06-27 14:26:11.0" UUID="441a3c40-0c84-11de-8c30-0800200c9a66" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. communis sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5002" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONBASE DTYPE="Taxon" ID="5003" CREATED="2016-06-27 14:26:11.0" UUID="e4acf200-63b6-11dd-ad8b-0800200c9a66" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. adenophora sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5003" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONBASE DTYPE="Taxon" ID="5004" CREATED="2016-06-27 14:26:11.0" UUID="596b1325-be50-4b0a-9aa2-3ecd610215f2" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" SECMICROREFERENCE="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="L. communis subsp. alpina sec. Sp.Pl." APPENDEDPHRASE="[null]" DOUBTFUL="false" PUBLISH="true" USENAMECACHE="false" EXCLUDED="false" TAXONSTATUSUNKNOWN="false" TAXONOMICCHILDRENCOUNT="0" UNPLACED="false" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5004" SEC_ID="5000" TAXONOMICPARENTCACHE_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="463d06e3-2665-43cc-8c70-cb658c81a738" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="Lapsana" APPENDEDPHRASE="[null]" FULLTITLECACHE="Lapsana" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5000" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="774" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5001" CREATED="2016-06-27 14:26:11.0" UUID="2b718c66-1853-45c9-9f8e-e03057194349" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="" PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5001" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="765" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5002" CREATED="2016-06-27 14:26:11.0" UUID="06a6a0fd-048e-45e5-aa32-1c7f2dc75421" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. communis" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. communis" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5002" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5003" CREATED="2016-06-27 14:26:11.0" UUID="6ce4f911-4932-4cfb-9793-2e45aaef59aa" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. adenophora" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. adenophora" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5003" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
+  <TAXONNAMEBASE DTYPE="BotanicalName" ID="5004" CREATED="2016-06-27 14:26:11.0" UUID="1621acc6-142b-4987-a1d1-475aa01489dc" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="L. communis subsp. alpina" APPENDEDPHRASE="[null]" FULLTITLECACHE="L. communis subsp. alpina" NOMENCLATURALMICROREFERENCE="[null]" PARSINGPROBLEM="0" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PROTECTEDFULLTITLECACHE="false" AUTHORSHIPCACHE="" BINOMHYBRID="false" GENUSORUNINOMIAL="[null]" HYBRIDFORMULA="false" INFRAGENERICEPITHET="[null]" INFRASPECIFICEPITHET="[null]" MONOMHYBRID="false" NAMECACHE="subsp." PROTECTEDAUTHORSHIPCACHE="false" PROTECTEDNAMECACHE="false" SPECIFICEPITHET="[null]" TRINOMHYBRID="false" NAMEAPPROBATION="[null]" SUBGENUSAUTHORSHIP="[null]" ANAMORPHIC="false" CULTIVARNAME="[null]" ACRONYM="[null]" BREED="[null]" ORIGINALPUBLICATIONYEAR="[null]" PUBLICATIONYEAR="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" HOMOTYPICALGROUP_ID="5004" NOMENCLATURALREFERENCE_ID="[null]" RANK_ID="763" BASIONYMAUTHORSHIP_ID="[null]" COMBINATIONAUTHORSHIP_ID="[null]" EXBASIONYMAUTHORSHIP_ID="[null]" EXCOMBINATIONAUTHORSHIP_ID="[null]"/>
+  <REFERENCE DTYPE="[null]" ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="b59c0842-fba3-4255-8e32-5a064303b8a2" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="true" TITLECACHE="Sp.Pl." DATEPUBLISHED_END="[null]" DATEPUBLISHED_FREETEXT="[null]" DATEPUBLISHED_START="[null]" EDITION="[null]" EDITOR="[null]" ISBN="[null]" ISSN="[null]" DOI="[null]" NOMENCLATURALLYRELEVANT="false" ORGANIZATION="[null]" PAGES="[null]" PARSINGPROBLEM="0" PLACEPUBLISHED="[null]" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PUBLISHER="[null]" REFERENCEABSTRACT="[null]" SERIESPART="[null]" TITLE="[null]" ABBREVTITLE="[null]" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="DB" URI="[null]" VOLUME="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" AUTHORSHIP_ID="[null]" INREFERENCE_ID="[null]" INSTITUTION_ID="[null]" SCHOOL_ID="[null]"/>
+  <REFERENCE DTYPE="[null]" ID="5001" CREATED="2016-06-27 14:26:11.0" UUID="3268a382-f51a-495e-8de6-763854944c7d" UPDATED="[null]" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="Reference [type=Book, id= 0, uuid=3268a382-f51a-495e-8de6-763854944c7d]" DATEPUBLISHED_END="[null]" DATEPUBLISHED_FREETEXT="[null]" DATEPUBLISHED_START="[null]" EDITION="[null]" EDITOR="[null]" ISBN="[null]" ISSN="[null]" DOI="[null]" NOMENCLATURALLYRELEVANT="false" ORGANIZATION="[null]" PAGES="[null]" PARSINGPROBLEM="0" PLACEPUBLISHED="[null]" PROBLEMENDS="-1" PROBLEMSTARTS="-1" PUBLISHER="[null]" REFERENCEABSTRACT="[null]" SERIESPART="[null]" TITLE="[null]" ABBREVTITLE="[null]" ABBREVTITLECACHE="" PROTECTEDABBREVTITLECACHE="false" REFTYPE="BK" URI="[null]" VOLUME="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" AUTHORSHIP_ID="[null]" INREFERENCE_ID="[null]" INSTITUTION_ID="[null]" SCHOOL_ID="[null]"/>
+  <CLASSIFICATION ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="4b266053-a841-4980-b548-3f21d8d7d712" UPDATED="2016-06-27 14:26:11.88" LSID_AUTHORITY="[null]" LSID_LSID="[null]" LSID_NAMESPACE="[null]" LSID_OBJECT="[null]" LSID_REVISION="[null]" PROTECTEDTITLECACHE="false" TITLECACHE="TestClassification" MICROREFERENCE="[null]" TIMEPERIOD_START="[null]" TIMEPERIOD_FREETEXT="[null]" TIMEPERIOD_END="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" NAME_ID="5000" REFERENCE_ID="[null]" ROOTNODE_ID="5000"/>
+  <TAXONNODE ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="06512abd-edf9-435b-a3d9-6cd6ede5aec8" UPDATED="2016-06-27 14:26:11.881" SORTINDEX="-1" TREEINDEX="#t5000#5000#" COUNTCHILDREN="1" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="[null]" REFERENCEFORPARENTCHILDRELATION_ID="[null]" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="[null]"/>
+  <TAXONNODE ID="5001" CREATED="2016-06-27 14:26:11.0" UUID="dcf4f891-c486-4d36-b1d1-39fae7a5df2a" UPDATED="[null]" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#" COUNTCHILDREN="1" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5000" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5000"/>
+  <TAXONNODE ID="5002" CREATED="2016-06-27 14:26:11.0" UUID="7dbe5319-ae7d-4140-bb3b-c34dc320d134" UPDATED="2016-06-27 14:26:11.882" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#5002#" COUNTCHILDREN="3" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5001" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5001"/>
+  <TAXONNODE ID="5003" CREATED="2016-06-27 14:26:11.0" UUID="4fd6c300-54b7-4f48-bad2-3126ab72a6d0" UPDATED="[null]" SORTINDEX="0" TREEINDEX="#t5000#5000#5001#5002#5003#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5002"/>
+  <TAXONNODE ID="5004" CREATED="2016-06-27 14:26:11.0" UUID="5523c20c-bbc2-4c89-8b36-e00e8314d252" UPDATED="2016-06-27 14:26:11.883" SORTINDEX="1" TREEINDEX="#t5000#5000#5001#5002#5004#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5003"/>
+  <TAXONNODE ID="5005" CREATED="2016-06-27 14:26:11.0" UUID="65671bba-0373-4998-8a7b-410a67a2ddcf" UPDATED="2016-06-27 14:26:11.884" SORTINDEX="2" TREEINDEX="#t5000#5000#5001#5002#5005#" COUNTCHILDREN="0" MICROREFERENCEFORPARENTCHILDRELATION="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" CLASSIFICATION_ID="5000" PARENT_ID="5002" REFERENCEFORPARENTCHILDRELATION_ID="5000" SYNONYMTOBEUSED_ID="[null]" TAXON_ID="5004"/>
+  <HOMOTYPICALGROUP ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="207c1e0c-ce60-4516-adf7-0ba5a61ee62f" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <HOMOTYPICALGROUP ID="5001" CREATED="2016-06-27 14:26:11.0" UUID="e18238ce-8d2c-4ac6-bf33-8f019012dfac" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <HOMOTYPICALGROUP ID="5002" CREATED="2016-06-27 14:26:11.0" UUID="85c073ca-bde7-4bdd-be40-e1783132f45e" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <HOMOTYPICALGROUP ID="5003" CREATED="2016-06-27 14:26:11.0" UUID="b2f33aa8-fb6e-4ca3-9ae4-6c6d49b08a71" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <HOMOTYPICALGROUP ID="5004" CREATED="2016-06-27 14:26:11.0" UUID="8ccf2a95-d355-4de1-8eda-ebd4b90e691d" UPDATED="[null]" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]"/>
+  <LANGUAGESTRING ID="5000" CREATED="2016-06-27 14:26:11.0" UUID="57a6a64a-59e5-41ed-92ab-f53c03b29b14" UPDATED="[null]" TEXT="TestClassification" CREATEDBY_ID="[null]" UPDATEDBY_ID="[null]" LANGUAGE_ID="406"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="AuditEvent" NEXT_VAL="5003"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="CdmMetaData" NEXT_VAL="5003"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="Classification" NEXT_VAL="5001"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="Extension" NEXT_VAL="5016"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="GrantedAuthorityImpl" NEXT_VAL="5011"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="HomotypicalGroup" NEXT_VAL="5005"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="LanguageString" NEXT_VAL="5001"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="PermissionGroup" NEXT_VAL="5002"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="Reference" NEXT_VAL="5002"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="TaxonBase" NEXT_VAL="5005"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="TaxonNameBase" NEXT_VAL="5005"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="TaxonNode" NEXT_VAL="5006"/>
+  <HIBERNATE_SEQUENCES SEQUENCE_NAME="UserAccount" NEXT_VAL="5001"/>
 </dataset>