Corrected bug in AuditEventDao
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / persistence / dao / hibernate / taxon / TaxonDaoHibernateImpl.java
index 9e5c2f52afe7379139d17742560c184bb7ebc1c8..b4eaed2845b2474447dd5d873a084541155c9b90 100644 (file)
@@ -8,11 +8,8 @@
  */\r
 package eu.etaxonomy.cdm.persistence.dao.hibernate.taxon;\r
 \r
-import java.lang.reflect.Field;\r
-import java.lang.reflect.InvocationTargetException;\r
-import java.lang.reflect.Method;\r
 import java.util.ArrayList;\r
-import java.util.Collections;\r
+import java.util.Collection;\r
 import java.util.Comparator;\r
 import java.util.HashSet;\r
 import java.util.Iterator;\r
@@ -23,67 +20,47 @@ import java.util.TreeSet;
 import java.util.UUID;\r
 \r
 import org.apache.log4j.Logger;\r
-import org.apache.lucene.analysis.SimpleAnalyzer;\r
 import org.apache.lucene.queryParser.ParseException;\r
-import org.apache.lucene.queryParser.QueryParser;\r
-import org.apache.lucene.search.Sort;\r
-import org.apache.lucene.search.SortField;\r
 import org.hibernate.Criteria;\r
 import org.hibernate.FetchMode;\r
 import org.hibernate.Hibernate;\r
-import org.hibernate.LazyInitializationException;\r
 import org.hibernate.Query;\r
-import org.hibernate.Transaction;\r
 import org.hibernate.criterion.Criterion;\r
-import org.hibernate.criterion.Order;\r
 import org.hibernate.criterion.Projections;\r
 import org.hibernate.criterion.Restrictions;\r
 import org.hibernate.envers.query.AuditEntity;\r
 import org.hibernate.envers.query.AuditQuery;\r
-import org.hibernate.search.FullTextQuery;\r
 import org.hibernate.search.FullTextSession;\r
 import org.hibernate.search.Search;\r
-import org.hibernate.search.SearchFactory;\r
 import org.springframework.beans.factory.annotation.Autowired;\r
 import org.springframework.beans.factory.annotation.Qualifier;\r
 import org.springframework.dao.DataAccessException;\r
 import org.springframework.stereotype.Repository;\r
-import org.springframework.util.ReflectionUtils;\r
 \r
-import eu.etaxonomy.cdm.model.common.Annotation;\r
-import eu.etaxonomy.cdm.model.common.Extension;\r
-import eu.etaxonomy.cdm.model.common.Marker;\r
-import eu.etaxonomy.cdm.model.common.OriginalSource;\r
+import eu.etaxonomy.cdm.model.common.LSID;\r
 import eu.etaxonomy.cdm.model.common.RelationshipBase;\r
-import eu.etaxonomy.cdm.model.description.DescriptionElementBase;\r
-import eu.etaxonomy.cdm.model.description.TaxonDescription;\r
-import eu.etaxonomy.cdm.model.media.Rights;\r
-import eu.etaxonomy.cdm.model.location.WaterbodyOrCountry;\r
+import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;\r
+import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;\r
+import eu.etaxonomy.cdm.model.location.NamedArea;\r
 import eu.etaxonomy.cdm.model.name.Rank;\r
-import eu.etaxonomy.cdm.model.name.TaxonNameBase;\r
-import eu.etaxonomy.cdm.model.occurrence.Collection;\r
-import eu.etaxonomy.cdm.model.occurrence.DeterminationEvent;\r
 import eu.etaxonomy.cdm.model.reference.ReferenceBase;\r
 import eu.etaxonomy.cdm.model.taxon.Synonym;\r
 import eu.etaxonomy.cdm.model.taxon.SynonymRelationship;\r
 import eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType;\r
 import eu.etaxonomy.cdm.model.taxon.Taxon;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonBase;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonNode;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationship;\r
 import eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType;\r
+import eu.etaxonomy.cdm.model.taxon.TaxonomicTree;\r
 import eu.etaxonomy.cdm.model.view.AuditEvent;\r
-import eu.etaxonomy.cdm.persistence.dao.BeanInitializer;\r
 import eu.etaxonomy.cdm.persistence.dao.QueryParseException;\r
-import eu.etaxonomy.cdm.persistence.dao.common.ISearchableDao;\r
-import eu.etaxonomy.cdm.persistence.dao.common.ITitledDao;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.AlternativeSpellingSuggestionParser;\r
-import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;\r
 import eu.etaxonomy.cdm.persistence.dao.hibernate.common.IdentifiableDaoBase;\r
 import eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao;\r
 import eu.etaxonomy.cdm.persistence.fetch.CdmFetch;\r
 import eu.etaxonomy.cdm.persistence.query.MatchMode;\r
 import eu.etaxonomy.cdm.persistence.query.OrderHint;\r
-import eu.etaxonomy.cdm.persistence.query.SelectMode;\r
 \r
 \r
 /**\r
@@ -95,25 +72,21 @@ import eu.etaxonomy.cdm.persistence.query.SelectMode;
 @Qualifier("taxonDaoHibernateImpl")\r
 public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {       \r
        private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;\r
-       \r
-       \r
-       @SuppressWarnings("unused")\r
        private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\r
-               \r
-       private String defaultField = "name.titleCache";\r
-       private Class<? extends TaxonBase> indexedClasses[]; \r
 \r
        public TaxonDaoHibernateImpl() {\r
                super(TaxonBase.class);\r
                indexedClasses = new Class[2];\r
                indexedClasses[0] = Taxon.class;\r
                indexedClasses[1] = Synonym.class;\r
+               super.defaultField = "name.titleCache";\r
        }\r
        \r
        @Autowired(required = false)   //TODO switched of because it caused problems when starting CdmApplicationController\r
        public void setAlternativeSpellingSuggestionParser(AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser) {\r
-               this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser;\r
+               this.alternativeSpellingSuggestionParser = alternativeSpellingSuggestionParser; \r
        }\r
+       \r
 \r
        /* (non-Javadoc)\r
         * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.ReferenceBase)\r
@@ -221,127 +194,423 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return (List<TaxonBase>)criteria.list();\r
        }\r
 \r
-       public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode,\r
+       public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, MatchMode matchMode,\r
                        Integer pageSize, Integer pageNumber) {\r
                \r
-               return getTaxaByName(queryString, matchMode, selectMode, null, pageSize, pageNumber);\r
+               return getTaxaByName(clazz, queryString, null, matchMode, null, pageSize, pageNumber, null);\r
        }\r
        \r
        public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode, \r
                        Boolean accepted, Integer pageSize, Integer pageNumber) {\r
                \r
                if (accepted == true) {\r
-                       return getTaxaByName(queryString, matchMode, SelectMode.TAXA, pageSize, pageNumber);\r
+                       return getTaxaByName(Taxon.class, queryString, matchMode, pageSize, pageNumber);\r
                } else {\r
-                       return getTaxaByName(queryString, matchMode, SelectMode.SYNONYMS, pageSize, pageNumber);\r
+                       return getTaxaByName(Synonym.class, queryString, matchMode, pageSize, pageNumber);\r
                }\r
        }\r
        \r
        \r
-       public List<TaxonBase> getTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode,\r
-                       ReferenceBase sec, Integer pageSize, Integer pageNumber) {\r
+       public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,\r
+                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, \r
+                       Integer pageNumber, List<String> propertyPaths) {\r
+                               \r
+               boolean doCount = false;\r
+               Query query = prepareTaxaByName(clazz, queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);\r
+               if (query != null){\r
+                       List<TaxonBase> results = query.list();\r
+                       results.addAll (prepareTaxaByCommonName(queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount).list());\r
+                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                       return results;\r
+               }\r
+               return new ArrayList<TaxonBase>();\r
+               \r
+       }\r
 \r
-               Criteria criteria = null;\r
-               Class<?> clazz = selectMode.criteria();\r
-               criteria = getSession().createCriteria(clazz);\r
+       public List<TaxonBase> getTaxaByCommonName(String queryString, TaxonomicTree taxonomicTree,\r
+                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, \r
+                       Integer pageNumber, List<String> propertyPaths) {\r
+                       boolean doCount = false;        \r
+                       Query query = prepareTaxaByCommonName(queryString, taxonomicTree, matchMode, namedAreas, pageSize, pageNumber, doCount);\r
+                       if (query != null){\r
+                               List<TaxonBase> results = query.list();\r
+                               defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+                               return results;\r
+                       }\r
+                       return new ArrayList<TaxonBase>();\r
                \r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
+       }\r
+       \r
+\r
+       /**\r
+        * @param clazz\r
+        * @param queryString\r
+        * @param taxonomicTree TODO\r
+        * @param matchMode\r
+        * @param namedAreas\r
+        * @param pageSize\r
+        * @param pageNumber\r
+        * @param doCount\r
+        * @return\r
+        * \r
+        * FIXME implement taxontree restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}\r
+        */\r
+       private Query prepareTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,\r
+                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount) {\r
+\r
+               //TODO ? checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");\r
+\r
+               String hqlQueryString = matchMode.queryStringFrom(queryString);\r
                \r
-               if (queryString != null) {\r
-                       String hqlQueryString = matchMode.queryStringFrom(queryString);\r
-                       if (matchMode == MatchMode.EXACT) {\r
-                               criteria.add(Restrictions.eq("name.nameCache", hqlQueryString));\r
+               String matchOperator;\r
+               if (matchMode == MatchMode.EXACT) {\r
+                       matchOperator = "=";\r
+               } else {\r
+                       matchOperator = "like";\r
+               }\r
+               \r
+               String selectWhat = (doCount ? "count(t)": "t");\r
+               \r
+               String hql = "";\r
+               Set<NamedArea> areasExpanded = new HashSet<NamedArea>();\r
+               if(namedAreas != null && namedAreas.size() > 0){\r
+                       // expand areas and restrict by distribution area\r
+                       List<NamedArea> childAreas;\r
+                       Query areaQuery = getSession().createQuery("select childArea from NamedArea as childArea left join childArea.partOf as parentArea where parentArea = :area");\r
+                       expandNamedAreas(namedAreas, areasExpanded, areaQuery);\r
+               }\r
+               boolean doAreaRestriction = areasExpanded.size() > 0;\r
+               \r
+               Set<UUID> namedAreasUuids = new HashSet<UUID>();\r
+               for (NamedArea area:areasExpanded){\r
+                       namedAreasUuids.add(area.getUuid());\r
+               }\r
+               \r
+               String taxonSubselect = null;\r
+               String synonymSubselect = null;\r
+               \r
+               if(taxonomicTree != null){\r
+                       \r
+                       if(doAreaRestriction){\r
+                               \r
+                               taxonSubselect = "select t from" +\r
+                                       " Distribution e" +\r
+                                       " join e.inDescription d" +\r
+                                       " join d.taxon t" +\r
+                                       " join t.name n " +\r
+                                       " join t.taxonNodes as tn "+\r
+                                       " where" +\r
+                                       " e.area.uuid in (:namedAreasUuids) AND" +\r
+                                       " tn.taxonomicTree = :taxonomicTree" +\r
+                                       " AND n.nameCache " + matchOperator + " :queryString";\r
+                               \r
+                               \r
+                               synonymSubselect = "select s from" +\r
+                                       " Distribution e" +\r
+                                       " join e.inDescription d" +\r
+                                       " join d.taxon t" + // the taxa\r
+                                       " join t.taxonNodes as tn "+\r
+                                       " join t.synonymRelations sr" +\r
+                                       " join sr.relatedFrom s" + // the synonyms\r
+                                       " join s.name sn"+ \r
+                                       " where" +\r
+                                       " e.area.uuid in (:namedAreasUuids) AND" +\r
+                                       " tn.taxonomicTree = :taxonomicTree" +\r
+                                       " AND sn.nameCache " + matchOperator + " :queryString";\r
+                               \r
                        } else {\r
-                               criteria.add(Restrictions.ilike("name.nameCache", hqlQueryString));\r
+                               \r
+                               taxonSubselect = "select t from" +\r
+                                       " Taxon t" +\r
+                                       " join t.name n " +\r
+                                       " join t.taxonNodes as tn "+\r
+                                       " where" +\r
+                                       " tn.taxonomicTree = :taxonomicTree" +\r
+                                       " AND n.nameCache " + matchOperator + " :queryString";\r
+                               \r
+                               synonymSubselect = "select s from" +\r
+                                       " Taxon t" + // the taxa\r
+                                       " join t.taxonNodes as tn "+\r
+                                       " join t.synonymRelations sr" +\r
+                                       " join sr.relatedFrom s" + // the synonyms\r
+                                       " join s.name sn"+ \r
+                                       " where" +\r
+                                       " tn.taxonomicTree = :taxonomicTree" +\r
+                                       " AND sn.nameCache " + matchOperator + " :queryString";\r
+                       }       \r
+               } else {\r
+                       \r
+                       if(doAreaRestriction){\r
+                               \r
+                               taxonSubselect = "select t from " +\r
+                                       " Distribution e" +\r
+                                       " join e.inDescription d" +\r
+                                       " join d.taxon t" +\r
+                                       " join t.name n "+\r
+                                       " where" +\r
+                                       (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +\r
+                                       " n.nameCache " + matchOperator + " :queryString";\r
+                               \r
+                               synonymSubselect = "select s from" +\r
+                                       " Distribution e" +\r
+                                       " join e.inDescription d" +\r
+                                       " join d.taxon t" + // the taxa\r
+                                       " join t.synonymRelations sr" +\r
+                                       " join sr.relatedFrom s" + // the synonyms\r
+                                       " join s.name sn"+ \r
+                                       " where" +\r
+                                       (doAreaRestriction ? " e.area.uuid in (:namedAreasUuids) AND" : "") +\r
+                                       " sn.nameCache " + matchOperator + " :queryString";\r
+                               \r
+                       } else {\r
+                               \r
+                               taxonSubselect = "select t from " +\r
+                                       " Taxon t" +\r
+                                       " join t.name n "+\r
+                                       " where" +\r
+                                       " n.nameCache " + matchOperator + " :queryString";\r
+\r
+                               synonymSubselect = "select s from" +\r
+                                       " Taxon t" + // the taxa\r
+                                       " join t.synonymRelations sr" +\r
+                                       " join sr.relatedFrom s" + // the synonyms\r
+                                       " join s.name sn"+ \r
+                                       " where" +\r
+                                       " sn.nameCache " + matchOperator + " :queryString";\r
                        }\r
+                       \r
+               \r
                }\r
                \r
-               if (sec != null && sec.getId() != 0) {\r
-                       criteria.add(Restrictions.eq("sec", sec ) );\r
+               \r
+               \r
+               // TODO  mysql needs  optimization:  see http://www.xaprb.com/blog/2006/04/30/how-to-optimize-subqueries-and-joins-in-mysql/#commen\r
+               Query subTaxon = null;\r
+               Query subSynonym = null;\r
+               if(clazz.equals(Taxon.class)){\r
+                       // find Taxa\r
+                       subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);\r
+                       //subTaxon = getSession().createQuery(taxonSubselect);\r
+                       \r
+                       if(doAreaRestriction){\r
+                               subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);\r
+                       }       \r
+                       if(taxonomicTree != null){\r
+                               subTaxon.setParameter("taxonomicTree", taxonomicTree);\r
+                       }\r
+               } else if(clazz.equals(Synonym.class)){\r
+                       // find synonyms\r
+                       subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);\r
+                       \r
+                       if(doAreaRestriction){\r
+                               subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);\r
+                       }               \r
+                       if(taxonomicTree != null){\r
+                               subSynonym.setParameter("taxonomicTree", taxonomicTree);\r
+                       }\r
+               } else {\r
+                       // find taxa and synonyms\r
+                       subSynonym = getSession().createQuery(synonymSubselect).setParameter("queryString", hqlQueryString);\r
+                       subTaxon = getSession().createQuery(taxonSubselect).setParameter("queryString", hqlQueryString);\r
+                       if(doAreaRestriction){\r
+                               subTaxon.setParameterList("namedAreasUuids", namedAreasUuids);\r
+                               subSynonym.setParameterList("namedAreasUuids", namedAreasUuids);\r
+                       }\r
+                       if(taxonomicTree != null){\r
+                               subTaxon.setParameter("taxonomicTree", taxonomicTree);\r
+                               subSynonym.setParameter("taxonomicTree", taxonomicTree);\r
+                       }\r
                }\r
                \r
-               criteria.addOrder(Order.asc("name.nameCache"));\r
-                \r
-               if(pageSize != null) {\r
-                       criteria.setMaxResults(pageSize);\r
-                       if(pageNumber != null) {\r
-                               criteria.setFirstResult(pageNumber * pageSize);\r
+               List<TaxonBase> taxa = new ArrayList<TaxonBase>();\r
+               List<TaxonBase> synonyms = new ArrayList<TaxonBase>();\r
+               if(clazz.equals(Taxon.class)){\r
+                       taxa = subTaxon.list();\r
+                       \r
+               }else if (clazz.equals(Synonym.class)){\r
+                       synonyms = subSynonym.list();\r
+               }else {\r
+                       taxa = subTaxon.list();\r
+                       synonyms = subSynonym.list();\r
+               }\r
+               if(clazz.equals(Taxon.class)){\r
+                       if  (taxa.size()>0){\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa)";\r
+                       }else{\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
+                       }\r
+               } else if(clazz.equals(Synonym.class) ){\r
+                       if (synonyms.size()>0){\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:synonyms)";             \r
+                       }else{\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
+                       }\r
+               } else {\r
+                       if(synonyms.size()>0 && taxa.size()>0){\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa) OR t in (:synonyms)";\r
+                       }else if (synonyms.size()>0 ){\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" \r
+                               + " where t in (:synonyms)";    \r
+                       } else if (taxa.size()>0 ){\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t in (:taxa) ";\r
+                       } else{\r
+                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
                        }\r
                }\r
-\r
-               List<TaxonBase> results = criteria.list();\r
-               return results;\r
                \r
-       }\r
+               if (hql == "") return null;\r
+               if(!doCount){\r
+                       hql += " order by t.titleCache"; //" order by t.name.nameCache";\r
+               }\r
        \r
-       public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {\r
+               Query query = getSession().createQuery(hql);\r
                \r
-               return countTaxaByName(queryString, matchMode, selectMode, null);\r
-       }\r
-\r
-       public Integer countTaxaByName(String queryString, \r
-                       MatchMode matchMode, SelectMode selectMode, ReferenceBase sec) {\r
-\r
-               Criteria criteria = null;\r
-               Class<?> clazz = selectMode.criteria();\r
-               criteria = getSession().createCriteria(clazz);\r
-\r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
-\r
-               if (queryString != null) {\r
-                       String hqlQueryString = matchMode.queryStringFrom(queryString);\r
-                       if (matchMode == MatchMode.EXACT) {\r
-                               criteria.add(Restrictions.eq("name.nameCache", hqlQueryString));\r
-                       } else {\r
-                               criteria.add(Restrictions.ilike("name.nameCache", hqlQueryString));\r
+               if(clazz.equals(Taxon.class) && taxa.size()>0){\r
+                       //find taxa\r
+                       query.setParameterList("taxa", taxa );\r
+               } else if(clazz.equals(Synonym.class) && synonyms.size()>0){\r
+                       // find synonyms\r
+                       query.setParameterList("synonyms", synonyms);\r
+                       \r
+               \r
+               } else {\r
+                       // find taxa and synonyms\r
+                       if (taxa.size()>0){\r
+                               query.setParameterList("taxa", taxa);\r
+                       }\r
+                       if (synonyms.size()>0){\r
+                               query.setParameterList("synonyms",synonyms);\r
+                       }\r
+                       if (taxa.size()== 0 && synonyms.size() == 0){\r
+                               return null;\r
                        }\r
                }\r
-\r
-               if (sec != null && sec.getId() != 0) {\r
-                       criteria.add(Restrictions.eq("sec", sec ) );\r
+               \r
+               if(pageSize != null &&  !doCount) {\r
+                       query.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                               query.setFirstResult(pageNumber * pageSize);\r
+                       }\r
                }\r
-\r
-               criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-               return (Integer)criteria.uniqueResult();\r
-\r
+               \r
+               return query;\r
        }\r
        \r
-       public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {\r
+       private Query prepareTaxaByCommonName(String queryString, TaxonomicTree taxonomicTree,\r
+                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount){\r
                \r
-               Criteria criteria = null;\r
-               if (accepted == true) {\r
-                       criteria = getSession().createCriteria(Taxon.class);\r
+               String matchOperator;\r
+               if (matchMode == MatchMode.EXACT) {\r
+                       matchOperator = "=";\r
                } else {\r
-                       criteria = getSession().createCriteria(Synonym.class);\r
+                       matchOperator = "like";\r
                }\r
-\r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
                \r
-               if (matchMode == MatchMode.EXACT) {\r
-                       criteria.add(Restrictions.eq("name.nameCache", matchMode.queryStringFrom(queryString)));\r
-               } else {\r
-                       criteria.add(Restrictions.ilike("name.nameCache", matchMode.queryStringFrom(queryString)));\r
+               String hql= "from Taxon t " +\r
+               "join t.descriptions d "+\r
+               "join d.descriptionElements e " +\r
+               "join e.feature f " +\r
+               "where f.supportsCommonTaxonName = true and e.name "+matchOperator+" :queryString";//and ls.text like 'common%'";\r
+               \r
+               Query query = getSession().createQuery(hql);\r
+               \r
+               query.setParameter("queryString", queryString);\r
+               \r
+               if(pageSize != null &&  !doCount) {\r
+                       query.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                               query.setFirstResult(pageNumber * pageSize);\r
+                       }\r
                }\r
+               return query;\r
+       }\r
+       \r
+       /* (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.ReferenceBase, java.util.Set)\r
+        */\r
+       public long countTaxaByName(Class<? extends TaxonBase> clazz, String queryString, TaxonomicTree taxonomicTree,\r
+               MatchMode matchMode, Set<NamedArea> namedAreas) {\r
                \r
-               criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-               return (Integer)criteria.uniqueResult();\r
+               boolean doCount = true;\r
+               Query query = prepareTaxaByName(clazz, queryString, taxonomicTree, matchMode, namedAreas, null, null, doCount);\r
+               if (query != null) {\r
+                       return (Long)query.uniqueResult();\r
+               }\r
+               return 0;\r
+               \r
+       }\r
+\r
+       /**\r
+        * @param namedAreas\r
+        * @param areasExpanded\r
+        * @param areaQuery\r
+        */\r
+       private void expandNamedAreas(Collection<NamedArea> namedAreas, Set<NamedArea> areasExpanded, Query areaQuery) {\r
+               List<NamedArea> childAreas;\r
+               for(NamedArea a : namedAreas){\r
+                       areasExpanded.add(a);\r
+                       areaQuery.setParameter("area", a);\r
+                       childAreas = areaQuery.list();\r
+                       if(childAreas.size() > 0){\r
+                               areasExpanded.addAll(childAreas);\r
+                               expandNamedAreas(childAreas, areasExpanded, areaQuery);\r
+                       }\r
+               }\r
        }\r
        \r
+//     /* (non-Javadoc)\r
+//      * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode)\r
+//      */\r
+//     public Integer countTaxaByName(String queryString, MatchMode matchMode, SelectMode selectMode) {                \r
+//             return countTaxaByName(queryString, matchMode, selectMode, null);\r
+//     }\r
+\r
+//     /* (non-Javadoc)\r
+//      * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, eu.etaxonomy.cdm.persistence.query.SelectMode, eu.etaxonomy.cdm.model.reference.ReferenceBase)\r
+//      */\r
+//     public Integer countTaxaByName(String queryString, \r
+//                     MatchMode matchMode, SelectMode selectMode, ReferenceBase sec) {\r
+//\r
+//             Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);\r
+//             return count.intValue();\r
+//\r
+//     }\r
+       \r
+//     public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {\r
+//             \r
+//             SelectMode selectMode = (accepted ? SelectMode.TAXA : SelectMode.SYNONYMS);\r
+//             Long count = countTaxaByName(queryString, matchMode, selectMode, null, null);\r
+//             return count.intValue();\r
+//     }\r
+       \r
 \r
        public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {\r
                return super.list(pagesize, page);\r
        }\r
 \r
        public List<Synonym> getAllSynonyms(Integer limit, Integer start) {\r
-               return super.list(Synonym.class, limit, start);\r
+               Criteria criteria = getSession().createCriteria(Synonym.class);\r
+               \r
+               if(limit != null) {\r
+                       criteria.setFirstResult(start);\r
+                       criteria.setMaxResults(limit);\r
+               }\r
+               \r
+               return criteria.list();\r
        }\r
 \r
        public List<Taxon> getAllTaxa(Integer limit, Integer start) {\r
-               return super.list(Taxon.class, limit, start);\r
+        Criteria criteria = getSession().createCriteria(Taxon.class);\r
+               \r
+               if(limit != null) {\r
+                       criteria.setFirstResult(start);\r
+                       criteria.setMaxResults(limit);\r
+               }\r
+               \r
+               return criteria.list();\r
        }\r
+       \r
+       \r
 \r
        public List<RelationshipBase> getAllRelationships(Integer limit, Integer start) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
@@ -390,47 +659,9 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                // actually solve it.\r
                getSession().merge(taxonBase);\r
                \r
-               for(Iterator<Annotation> iterator = taxonBase.getAnnotations().iterator(); iterator.hasNext();) {\r
-                       Annotation annotation = iterator.next();\r
-                   annotation.setAnnotatedObj(null);\r
-                   iterator.remove();\r
-                   getSession().delete(annotation);\r
-           }\r
-               \r
-               for(Iterator<Marker> iterator = taxonBase.getMarkers().iterator(); iterator.hasNext();) {\r
-                       Marker marker = iterator.next();\r
-                   marker.setMarkedObj(null);\r
-                   iterator.remove();\r
-                   getSession().delete(marker);\r
-           }\r
-               \r
-               for(Iterator<Extension> iterator = taxonBase.getExtensions().iterator(); iterator.hasNext();) {\r
-                       Extension extension = iterator.next();\r
-                   extension.setExtendedObj(null);\r
-                   iterator.remove();\r
-                   getSession().delete(extension);\r
-           }\r
-               \r
-               for(Iterator<OriginalSource> iterator = taxonBase.getSources().iterator(); iterator.hasNext();) {\r
-                       OriginalSource source = iterator.next();\r
-                   source.setSourcedObj(null);\r
-                   iterator.remove();\r
-                   getSession().delete(source);\r
-           }\r
-\r
-               for(Iterator<Rights> iterator = taxonBase.getRights().iterator(); iterator.hasNext();) {\r
-                       Rights rights = iterator.next();\r
-                   iterator.remove();\r
-                   getSession().delete(rights);\r
-           }\r
-               \r
                if (taxonBase instanceof Taxon){ //     is Taxon\r
-                       //taxonRelationships\r
-                       Taxon taxon = (Taxon)taxonBase;\r
-                                               \r
-                       for (Iterator<TaxonRelationship> iterator = taxon.getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
+                       for (Iterator<TaxonRelationship> iterator = ((Taxon)taxonBase).getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
                                TaxonRelationship relationFromThisTaxon = iterator.next();\r
-                               iterator.remove();\r
                                \r
                                // decrease children count of taxonomic parent by one\r
                                if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
@@ -439,64 +670,9 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                                                toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);     \r
                                        }\r
                                }\r
-                               relationFromThisTaxon.setToTaxon(null);\r
-                               relationFromThisTaxon.setFromTaxon(null);\r
-                               getSession().delete(relationFromThisTaxon);\r
-                       }\r
-                       \r
-                       for (Iterator<TaxonRelationship> iterator = taxon.getRelationsToThisTaxon().iterator(); iterator.hasNext();){\r
-                               TaxonRelationship relationToThisTaxon = iterator.next();\r
-                               iterator.remove();\r
-                               \r
-                // set parent cache of child to null\r
-                               if (relationToThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
-                                       Taxon fromTaxon = relationToThisTaxon.getFromTaxon(); // child\r
-                                       if (fromTaxon != null) {\r
-                                               fromTaxon.nullifyTaxonomicParent();\r
-                                       }\r
-                               }\r
-                               relationToThisTaxon.setFromTaxon(null);\r
-                               relationToThisTaxon.setToTaxon(null);\r
-                               getSession().delete(relationToThisTaxon);\r
                        }\r
-                       \r
-                       //SynonymRelationships\r
-                       for (Iterator<SynonymRelationship> iterator = taxon.getSynonymRelations().iterator(); iterator.hasNext();){\r
-                               SynonymRelationship synonymRelation = iterator.next();\r
-                               iterator.remove();\r
-                               synonymRelation.setAcceptedTaxon(null);\r
-                               synonymRelation.setSynonym(null);\r
-                               getSession().delete(synonymRelation);\r
-                       } \r
-                       \r
-                       // Descriptions\r
-                       for (Iterator<TaxonDescription> iterDesc = taxon.getDescriptions().iterator(); iterDesc.hasNext();) {\r
-                               TaxonDescription taxonDescription = iterDesc.next();\r
-                               iterDesc.remove();\r
-                               //taxonDescription.setTaxon(null);\r
-                               Field field = ReflectionUtils.findField(TaxonDescription.class, "taxon", Taxon.class);\r
-                               ReflectionUtils.makeAccessible(field);\r
-                               ReflectionUtils.setField(field, taxonDescription, null);\r
-                               for (Iterator<DescriptionElementBase> iterDescElem = \r
-                                       taxonDescription.getElements().iterator(); iterDescElem.hasNext();) {\r
-                                       DescriptionElementBase descriptionElement = iterDescElem.next();\r
-                                       iterDescElem.remove();\r
-                                       getSession().delete(descriptionElement);\r
-                               }\r
-                               getSession().delete(taxonDescription);\r
-                       }\r
-                       \r
-                       taxon.nullifyTaxonomicParent();\r
-\r
-               } else { //is Synonym\r
-                       Synonym synonym = (Synonym)taxonBase;\r
-                       for (Iterator<SynonymRelationship> iterator = synonym.getSynonymRelations().iterator(); iterator.hasNext();){\r
-                               SynonymRelationship synonymRelation = iterator.next();\r
-                               iterator.remove();\r
-                               synonymRelation.setAcceptedTaxon(null);\r
-                               synonymRelation.setSynonym(null);\r
-                       } ;\r
                }\r
+               \r
                return super.delete(taxonBase);\r
        }\r
 \r
@@ -533,24 +709,23 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return result;\r
        }\r
 \r
-       public int countRelatedTaxa(Taxon taxon, TaxonRelationshipType type) {\r
+       public int countTaxonRelationships(Taxon taxon, TaxonRelationshipType type, Direction direction) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
                    Query query = null;\r
                \r
                    if(type == null) {\r
-                           query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo");\r
+                           query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon");\r
                    } else {\r
-                           query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship.relatedTo = :relatedTo and taxonRelationship.type = :type");\r
+                           query = getSession().createQuery("select count(taxonRelationship) from TaxonRelationship taxonRelationship where taxonRelationship."+direction+" = :relatedTaxon and taxonRelationship.type = :type");\r
                            query.setParameter("type",type);\r
                    }\r
-               \r
-                   query.setParameter("relatedTo", taxon);\r
+                   query.setParameter("relatedTaxon", taxon);\r
                \r
                    return ((Long)query.uniqueResult()).intValue();\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
+                       query.add(AuditEntity.relatedId(direction.toString()).eq(taxon.getId()));\r
                        query.addProjection(AuditEntity.id().count("id"));\r
                        \r
                        if(type != null) {\r
@@ -564,18 +739,14 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
        public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Query query = null;\r
-\r
-                       if(type == null) {\r
-                               query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo");\r
-                       } else {\r
-                               query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship.relatedTo = :relatedTo and synonymRelationship.type = :type");\r
-                               query.setParameter("type",type);\r
-                       }\r
+                       Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
 \r
-                       query.setParameter("relatedTo", taxon);\r
-\r
-                       return ((Long)query.uniqueResult()).intValue();\r
+                       criteria.add(Restrictions.eq("relatedTo", taxon));\r
+                   if(type != null) {\r
+                       criteria.add(Restrictions.eq("type", type));\r
+                   } \r
+                   criteria.setProjection(Projections.rowCount());\r
+                       return (Integer)criteria.uniqueResult();\r
                } else {\r
                        AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());\r
                        query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
@@ -588,59 +759,33 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        return ((Long)query.getSingleResult()).intValue();\r
                }\r
        }\r
+       \r
+       public int countSynonyms(Synonym synonym, SynonymRelationshipType type) {\r
+               AuditEvent auditEvent = getAuditEventFromContext();\r
+               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+                       Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
 \r
-       public int count(Class<? extends TaxonBase> clazz, String queryString) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.count(String queryString, Boolean accepted)");\r
-        QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
-               \r
-               try {\r
-                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
-                       \r
-                       FullTextSession fullTextSession = Search.getFullTextSession(this.getSession());\r
-                       org.hibernate.search.FullTextQuery fullTextQuery = null;\r
+                       criteria.add(Restrictions.eq("relatedFrom", synonym));\r
+                   if(type != null) {\r
+                       criteria.add(Restrictions.eq("type", type));\r
+                   } \r
+                   \r
+                   criteria.setProjection(Projections.rowCount());\r
+                       return (Integer)criteria.uniqueResult();\r
+               } else {\r
+                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());\r
+                       query.add(AuditEntity.relatedId("relatedFrom").eq(synonym.getId()));\r
+                       query.addProjection(AuditEntity.id().count("id"));\r
                        \r
-                       if(clazz == null) {\r
-                               fullTextQuery = fullTextSession.createFullTextQuery(query, type);\r
-                       } else {\r
-                               fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);\r
-                       }\r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+                   }\r
                        \r
-                   Integer  result = fullTextQuery.getResultSize();\r
-                   return result;\r
-\r
-               } catch (ParseException e) {\r
-                       throw new QueryParseException(e, queryString);\r
-               }\r
-       }\r
-       \r
-       public int countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(String queryString, Boolean accepted, ReferenceBase sec)");\r
-               Criteria criteria = null;\r
-               \r
-               if (accepted == true) {\r
-                       criteria = getSession().createCriteria(Taxon.class);\r
-               } else {\r
-                       criteria = getSession().createCriteria(Synonym.class);\r
-               }\r
-               \r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
-\r
-               if (sec != null){\r
-                       if(sec.getId() == 0){\r
-                               getSession().save(sec);\r
-                       }\r
-                       criteria.add(Restrictions.eq("sec", sec ) );\r
-               }\r
-               if (queryString != null) {\r
-                       criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
+                       return ((Long)query.getSingleResult()).intValue();\r
                }\r
-               criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-               \r
-               return (Integer)criteria.uniqueResult();\r
        }\r
 \r
-       public int countTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial,   String infraGenericEpithet, String specificEpithet,     String infraSpecificEpithet, Rank rank) {\r
+       public int countTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet,       String infraSpecificEpithet, Rank rank) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.countTaxaByName(Boolean accepted, String genusOrUninomial,   String infraGenericEpithet, String specificEpithet,     String infraSpecificEpithet, Rank rank)");\r
         Criteria criteria = null;\r
                \r
@@ -732,7 +877,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                return (List<TaxonBase>)criteria.list();\r
        }\r
 \r
-       public List<TaxonRelationship> getRelatedTaxa(Taxon taxon,      TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+       public List<TaxonRelationship> getTaxonRelationships(Taxon taxon,       TaxonRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths, Direction direction) {\r
                AuditEvent auditEvent = getAuditEventFromContext();\r
                if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
                        Criteria criteria = getSession().createCriteria(TaxonRelationship.class);\r
@@ -846,52 +991,57 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                        return result;\r
                }\r
        }\r
-\r
-       public List<TaxonBase> search(Class<? extends TaxonBase> clazz, String queryString,Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths)  {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.searchTaxa(String queryString, Boolean accepted,     Integer pageSize, Integer pageNumber)");\r
-               QueryParser queryParser = new QueryParser(defaultField, new SimpleAnalyzer());\r
-               List<TaxonBase> results = new ArrayList<TaxonBase>();\r
-                \r
-               try {\r
-                       org.apache.lucene.search.Query query = queryParser.parse(queryString);\r
+       \r
+       public List<SynonymRelationship> getSynonyms(Synonym synonym, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
+               AuditEvent auditEvent = getAuditEventFromContext();\r
+               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+            Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
+            \r
+                       criteria.add(Restrictions.eq("relatedFrom", synonym));\r
+                   if(type != null) {\r
+                       criteria.add(Restrictions.eq("type", type));\r
+                   } \r
+               \r
+            addOrder(criteria,orderHints);\r
+               \r
+                   if(pageSize != null) {\r
+                       criteria.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                               criteria.setFirstResult(pageNumber * pageSize);\r
+                       } else {\r
+                               criteria.setFirstResult(0);\r
+                       }\r
+                   }\r
+               \r
+                   List<SynonymRelationship> result = (List<SynonymRelationship>)criteria.list();\r
+                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+                   \r
+                   return result;\r
+               } else {\r
+                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(SynonymRelationship.class,auditEvent.getRevisionNumber());\r
+                       query.add(AuditEntity.relatedId("relatedFrom").eq(synonym.getId()));\r
                        \r
-                       FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-                       org.hibernate.search.FullTextQuery fullTextQuery = null;\r
+                       if(type != null) {\r
+                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+                   }\r
                        \r
-                       if(clazz == null) {\r
-                               fullTextQuery = fullTextSession.createFullTextQuery(query, TaxonBase.class);\r
-                       } else {\r
-                               fullTextQuery = fullTextSession.createFullTextQuery(query, clazz);\r
-                       }\r
+                       if(pageSize != null) {\r
+                       query.setMaxResults(pageSize);\r
+                       if(pageNumber != null) {\r
+                           query.setFirstResult(pageNumber * pageSize);\r
+                       } else {\r
+                           query.setFirstResult(0);\r
+                       }\r
+                   }\r
                        \r
-                       addOrder(fullTextQuery,orderHints);\r
+                       List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
+                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
                        \r
-                   if(pageSize != null) {\r
-                       fullTextQuery.setMaxResults(pageSize);\r
-                           if(pageNumber != null) {\r
-                               fullTextQuery.setFirstResult(pageNumber * pageSize);\r
-                           } else {\r
-                               fullTextQuery.setFirstResult(0);\r
-                           }\r
-                       }\r
-                   \r
-                   List<TaxonBase> result = (List<TaxonBase>)fullTextQuery.list();\r
-                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                   return result;\r
-\r
-               } catch (ParseException e) {\r
-                       throw new QueryParseException(e, queryString);\r
+                       return result;\r
                }\r
        }\r
        \r
-       public void purgeIndex() {\r
-               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-               for(Class clazz : indexedClasses) {\r
-                   fullTextSession.purgeAll(clazz); // remove all taxon base from indexes\r
-               }\r
-               fullTextSession.flushToIndexes();\r
-       }\r
-\r
+       @Override\r
        public void rebuildIndex() {\r
                FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
                \r
@@ -902,15 +1052,7 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                fullTextSession.flushToIndexes();\r
        }\r
        \r
-       public void optimizeIndex() {\r
-               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-               SearchFactory searchFactory = fullTextSession.getSearchFactory();\r
-               for(Class clazz : indexedClasses) {\r
-               searchFactory.optimize(clazz); // optimize the indices ()\r
-               }\r
-           fullTextSession.flushToIndexes();\r
-       }\r
-\r
+       @Override\r
        public String suggestQuery(String queryString) {\r
                checkNotInPriorView("TaxonDaoHibernateImpl.suggestQuery(String queryString)");\r
                String alternativeQueryString = null;\r
@@ -930,4 +1072,95 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
                }\r
                return alternativeQueryString;\r
        }\r
+       \r
+       /*\r
+        * (non-Javadoc)\r
+        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.TaxonomicTree)\r
+        */\r
+       public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByTaxonomicTree(TaxonomicTree taxonomicTree) {\r
+\r
+               int taxonomicTreeId = taxonomicTree.getId();\r
+               \r
+               String queryString = "SELECT nodes.uuid, taxa.titleCache FROM TaxonNode AS nodes LEFT JOIN TaxonBase AS taxa ON nodes.taxon_id = taxa.id WHERE taxa.DTYPE = 'Taxon' AND nodes.taxonomictree_id = " + taxonomicTreeId;\r
+               \r
+               List<Object[]> result = getSession().createSQLQuery(queryString).list();\r
+                               \r
+               if(result.size() == 0){\r
+                       return null;\r
+               }else{\r
+                       List<UuidAndTitleCache<TaxonNode>> list = new ArrayList<UuidAndTitleCache<TaxonNode>>(result.size()); \r
+                       \r
+                       for (Object object : result){\r
+                               \r
+                               Object[] objectArray = (Object[]) object;\r
+                               \r
+                               UUID uuid = UUID.fromString((String) objectArray[0]);\r
+                               String titleCache = (String) objectArray[1];\r
+                               \r
+                               list.add(new UuidAndTitleCache(TaxonNode.class, uuid, titleCache));\r
+                       }\r
+                       \r
+                       return list;    \r
+               }\r
+       }\r
+       \r
+       \r
+       public class UuidAndTitleCacheOfAcceptedTaxon{\r
+               UUID uuid;\r
+               \r
+               String titleCache;\r
+\r
+               public UuidAndTitleCacheOfAcceptedTaxon(UUID uuid, String titleCache){\r
+                       this.uuid = uuid;\r
+                       this.titleCache = titleCache;\r
+               }\r
+               \r
+               public UUID getUuid() {\r
+                       return uuid;\r
+               }\r
+\r
+               public void setUuid(UUID uuid) {\r
+                       this.uuid = uuid;\r
+               }\r
+\r
+               public String getTitleCache() {\r
+                       return titleCache;\r
+               }\r
+\r
+               public void setTitleCache(String titleCache) {\r
+                       this.titleCache = titleCache;\r
+               }\r
+       }\r
+       \r
+       @Override\r
+       public TaxonBase find(LSID lsid) {\r
+               TaxonBase taxonBase = super.find(lsid);\r
+               if(taxonBase != null) {\r
+                       List<String> propertyPaths = new ArrayList<String>();\r
+                       propertyPaths.add("createdBy");\r
+                       propertyPaths.add("updatedBy");\r
+                       propertyPaths.add("name");\r
+                       propertyPaths.add("sec");\r
+                       propertyPaths.add("relationsToThisTaxon");\r
+                       propertyPaths.add("relationsToThisTaxon.fromTaxon");\r
+                       propertyPaths.add("relationsToThisTaxon.toTaxon");\r
+                       propertyPaths.add("relationsFromThisTaxon");\r
+                       propertyPaths.add("relationsFromThisTaxon.toTaxon");\r
+                       propertyPaths.add("relationsToThisTaxon.type");\r
+                       propertyPaths.add("synonymRelations");\r
+                       propertyPaths.add("synonymRelations.synonym");\r
+                       propertyPaths.add("synonymRelations.type");\r
+                       propertyPaths.add("descriptions");\r
+                       \r
+                       defaultBeanInitializer.initialize(taxonBase, propertyPaths);\r
+               }\r
+               return taxonBase;\r
+       }\r
+\r
+       public List<TaxonBase> getTaxaByCommonName(String queryString,\r
+                       TaxonomicTree taxonomicTree, MatchMode matchMode,\r
+                       Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber) {\r
+               // TODO Auto-generated method stub\r
+               return null;\r
+       }\r
 }\r