related to #2664 (Specimen maps are not shown in cyprus dev portal) - now the occurre...
authorAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Tue, 29 Nov 2011 14:26:36 +0000 (14:26 +0000)
committerAndreas Kohlbecker <a.kohlbecker@bgbm.org>
Tue, 29 Nov 2011 14:26:36 +0000 (14:26 +0000)
.gitattributes
cdmlib-commons/src/main/java/eu/etaxonomy/cdm/common/CdmUtils.java
cdmlib-io/src/test/resources/eu/etaxonomy/cdm/applicationContext-test.xml
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AnnotationTypeAutoInitializer.java [new file with mode: 0644]
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AutoPropertyInitializer.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/common/DaoBase.java
cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/hibernate/taxon/TaxonDaoHibernateImpl.java
cdmlib-persistence/src/main/resources/eu/etaxonomy/cdm/persistence.xml
cdmlib-remote/src/main/resources/eu/etaxonomy/cdm/remote/json/jsonConfigurations.xml

index c0d60e69bdadb7ba15c7576327621eeec217a9b3..15b4e4ed2ea3e5c6ab45d795171973501c77e2e8 100644 (file)
@@ -1139,6 +1139,7 @@ cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v30_31/TermUpd
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v30_31/TermUpdater_314_315.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/database/update/v30_31/TermUpdater_31_311.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AbstractBeanInitializer.java -text
+cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AnnotationTypeAutoInitializer.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AutoPropertyInitializer.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/BeanInitializer.java -text
 cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/IAlternativeSpellingSuggestionParser.java -text
index 27d735a6ec7a67fcef7d16c88fbe42ba83c3d622..02e23d01bb9efe126e8d5d7bd7776c71ac6aee9d 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$\r
 /**\r
 * Copyright (C) 2007 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
@@ -36,224 +36,235 @@ import org.apache.log4j.Logger;
  *\r
  */\r
 public class CdmUtils {\r
-       private static final Logger logger = Logger.getLogger(CdmUtils.class);\r
-       \r
-       \r
-       static final String MUST_EXIST_FILE = "MUST-EXIST.txt";\r
-       \r
-       //folder seperator\r
-       static String folderSeperator;\r
-\r
-       \r
-       public static String getHomeDir() throws IOException{\r
-               String homeDirString = System.getenv("USERPROFILE") != null ? System.getenv("USERPROFILE") : System.getProperty("user.home");\r
-               \r
-               if( ! new File(homeDirString).canWrite()){\r
-                       throw new IOException("Can not write to home directory. Assumed path is: " + homeDirString);\r
-               }\r
-               \r
-               return homeDirString;\r
-       }\r
-\r
-       /**\r
-        * Returns the an InputStream for a read-only source\r
-        * @param resourceFileName the resources path within the classpath(!)\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       public static InputStream getReadableResourceStream(String resourceFileName) \r
-                       throws IOException{\r
-               InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);\r
-               return urlStream;\r
-       }\r
-       \r
-       /**\r
-        * Returns the an InputStream for a read-only source\r
-        * @param resourceFileName the resources path within the classpath(!)\r
-        * @return\r
-        * @throws IOException\r
-        */\r
-       public static InputStreamReader getUtf8ResourceReader(String resourceFileName) \r
-                       throws IOException{\r
-               InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);\r
-               InputStreamReader inputStreamReader = new InputStreamReader(urlStream, "UTF8");\r
-               return inputStreamReader;\r
-       }\r
-\r
-       \r
-       /**\r
-        * @return\r
-        */\r
-       static public String getFolderSeperator(){\r
-               if (folderSeperator == null){\r
-                       URL url = CdmUtils.class.getResource("/"+ MUST_EXIST_FILE);\r
-                       if ( url != null && ! urlIsJarOrBundle(url) ){\r
-                               folderSeperator =  File.separator;\r
-                       }else{\r
-                               folderSeperator = "/";\r
-                       }\r
-               }\r
-               return folderSeperator;\r
-       }\r
-       \r
-       \r
-       /**\r
-        * @param url\r
-        * @return\r
-        */\r
-       static private boolean urlIsJarOrBundle(URL url){\r
-               return url.getProtocol().startsWith("jar") || url.getProtocol().startsWith("bundleresource");\r
-       }\r
-       \r
-       /**\r
-        * Returns the file name for the file in which 'clazz' is to be found (helps finding according libraries)\r
-        * @param clazz\r
-        * @return\r
-        */\r
-       static public String findLibrary(Class<?> clazz){\r
-               String result = null;\r
-               if (clazz != null){\r
-                       String fullPackageName = clazz.getCanonicalName();\r
-                       fullPackageName = fullPackageName.replace(".", "/");\r
-                       URL url = CdmUtils.class.getResource("/" + fullPackageName + ".class" );\r
-                       if (url != null){\r
-                               result = url.getFile();\r
-                       }else{\r
-                               result = "";\r
-                       }\r
-                       logger.debug("LibraryURL for " + clazz.getCanonicalName() + " : " + result);\r
-               }\r
-               return result;\r
-       }\r
-       \r
-       static public String testMe(){\r
-               String message = "This is a test";\r
-               System.out.println(message);\r
-               return message;\r
-       }\r
-       \r
-       static public String readInputLine(String inputQuestion){\r
-               try {\r
-                       \r
-                       System.out.print(inputQuestion);\r
-                       BufferedReader in = new BufferedReader( new java.io.InputStreamReader( System.in )); \r
-                       String input; \r
-                       input = in.readLine(); \r
-                       return input;\r
-               } catch (IOException e) {\r
-                       logger.warn("IOExeption");\r
-                       return null;\r
-               }\r
-       }\r
-       \r
-\r
-       /**\r
-        * Returns the trimmed value string if value is not <code>null</code>. \r
-        * Returns the empty string if value is <code>null</code>.\r
-        * @param value\r
-        * @return\r
-        */\r
-       static public String NzTrim(String value){\r
-               return (value == null ? "" : value);\r
-       }\r
-\r
-       \r
-       /**\r
-        * Returns value if value is not <code>null</code>. Returns empty string if value is <code>null</code>.\r
-        * @param value\r
-        * @return\r
-        */\r
-       static public String Nz(String value){\r
-               return (value == null ? "" : value);\r
-       }\r
-\r
-       /**\r
-        * Returns value if value is not <code>null</code>. Returns defaultValue if value is <code>null</code>.\r
-        * @param value\r
-        * @return\r
-        */\r
-       static public String Nz(String value, String defaultValue){\r
-               return (value == null ? defaultValue : value);\r
-       }\r
-       \r
-       /**\r
-        * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.\r
-        * @param value\r
-        * @return\r
-        */\r
-       static public Integer Nz(Integer value){\r
-               return (value == null ? 0 : value);\r
-       }\r
-\r
-       /**\r
-        * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.\r
-        * @param value\r
-        * @return\r
-        */\r
-       static public Long Nz(Long value){\r
-               return (value == null ? 0 : value);\r
-       }\r
-               \r
-       /**\r
-        * Concatenates an array of strings using the defined seperator.<BR>\r
-        * <code>Null</code> values are interpreted as empty strings.<BR>\r
-        * If all strings are <code>null</code> then <code>null</code> is returned.\r
-        * @param strings\r
-        * @param seperator\r
-        * @return String \r
-        */\r
-       static public String concat(CharSequence separator, String[] strings){\r
-               String result = "";\r
-               boolean allNull = true;\r
-               for (String string : strings){\r
-                       if (string != null){\r
-                               if (result.length() > 0 && string.length() > 0){\r
-                                       result += separator;\r
-                               }\r
-                               result += string;\r
-                               allNull = false;\r
-                       }\r
-               }\r
-               //if all strings are null result should be null, not ""\r
-               if (allNull){\r
-                       return null;\r
-               }else {\r
-                       return result;\r
-               }\r
-       }\r
-\r
-       /**\r
-        * Concatenates two strings, using the defined seperator.<BR>\r
-        * <code>Null</code> values are interpreted as empty Strings.<BR>\r
-        * If both strings are <code>null</code> then <code>null</code> is returned.\r
-        * @see #concat(CharSequence, String[]) \r
-        * @param seperator\r
-        * @param string1\r
-        * @param string2\r
-        * @return String \r
-        */\r
-       static public String concat(CharSequence separator, String string1, String string2){\r
-               String[] strings = {string1, string2};\r
-               return concat(separator, strings);\r
-       }\r
-\r
-       \r
+    private static final String CDM_FOLDER_NAME = ".cdmLibrary";\r
+\r
+\r
+    private static final Logger logger = Logger.getLogger(CdmUtils.class);\r
+\r
+\r
+    static final String MUST_EXIST_FILE = "MUST-EXIST.txt";\r
+\r
+    //folder seperator\r
+    static String folderSeperator;\r
+\r
+    //TODO refactor to: public static File getUserHomeDir()\r
+    public static String getHomeDir() throws IOException{\r
+        //TODO why do we need System.getenv("USERPROFILE")? System.getProperty("user.home") is fully sufficient!!\r
+        String homeDirString = System.getenv("USERPROFILE") != null ? System.getenv("USERPROFILE") : System.getProperty("user.home");\r
+\r
+        if( ! new File(homeDirString).canWrite()){\r
+            throw new IOException("Can not write to home directory. Assumed path is: " + homeDirString);\r
+        }\r
+\r
+        return homeDirString;\r
+    }\r
+\r
+    public static File getCdmHomeDir() {\r
+        return new File(System.getProperty("user.home")+File.separator+CDM_FOLDER_NAME+File.separator);\r
+    }\r
+\r
+\r
+\r
+\r
+    /**\r
+     * Returns the an InputStream for a read-only source\r
+     * @param resourceFileName the resources path within the classpath(!)\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    public static InputStream getReadableResourceStream(String resourceFileName)\r
+            throws IOException{\r
+        InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);\r
+        return urlStream;\r
+    }\r
+\r
+    /**\r
+     * Returns the an InputStream for a read-only source\r
+     * @param resourceFileName the resources path within the classpath(!)\r
+     * @return\r
+     * @throws IOException\r
+     */\r
+    public static InputStreamReader getUtf8ResourceReader(String resourceFileName)\r
+            throws IOException{\r
+        InputStream urlStream = CdmUtils.class.getResourceAsStream("/"+ resourceFileName);\r
+        InputStreamReader inputStreamReader = new InputStreamReader(urlStream, "UTF8");\r
+        return inputStreamReader;\r
+    }\r
+\r
+\r
+    /**\r
+     * @return\r
+     */\r
+    static public String getFolderSeperator(){\r
+        if (folderSeperator == null){\r
+            URL url = CdmUtils.class.getResource("/"+ MUST_EXIST_FILE);\r
+            if ( url != null && ! urlIsJarOrBundle(url) ){\r
+                folderSeperator =  File.separator;\r
+            }else{\r
+                folderSeperator = "/";\r
+            }\r
+        }\r
+        return folderSeperator;\r
+    }\r
+\r
+\r
+    /**\r
+     * @param url\r
+     * @return\r
+     */\r
+    static private boolean urlIsJarOrBundle(URL url){\r
+        return url.getProtocol().startsWith("jar") || url.getProtocol().startsWith("bundleresource");\r
+    }\r
+\r
+    /**\r
+     * Returns the file name for the file in which 'clazz' is to be found (helps finding according libraries)\r
+     * @param clazz\r
+     * @return\r
+     */\r
+    static public String findLibrary(Class<?> clazz){\r
+        String result = null;\r
+        if (clazz != null){\r
+            String fullPackageName = clazz.getCanonicalName();\r
+            fullPackageName = fullPackageName.replace(".", "/");\r
+            URL url = CdmUtils.class.getResource("/" + fullPackageName + ".class" );\r
+            if (url != null){\r
+                result = url.getFile();\r
+            }else{\r
+                result = "";\r
+            }\r
+            logger.debug("LibraryURL for " + clazz.getCanonicalName() + " : " + result);\r
+        }\r
+        return result;\r
+    }\r
+\r
+    static public String testMe(){\r
+        String message = "This is a test";\r
+        System.out.println(message);\r
+        return message;\r
+    }\r
+\r
+    static public String readInputLine(String inputQuestion){\r
+        try {\r
+\r
+            System.out.print(inputQuestion);\r
+            BufferedReader in = new BufferedReader( new java.io.InputStreamReader( System.in ));\r
+            String input;\r
+            input = in.readLine();\r
+            return input;\r
+        } catch (IOException e) {\r
+            logger.warn("IOExeption");\r
+            return null;\r
+        }\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns the trimmed value string if value is not <code>null</code>.\r
+     * Returns the empty string if value is <code>null</code>.\r
+     * @param value\r
+     * @return\r
+     */\r
+    static public String NzTrim(String value){\r
+        return (value == null ? "" : value);\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns value if value is not <code>null</code>. Returns empty string if value is <code>null</code>.\r
+     * @param value\r
+     * @return\r
+     */\r
+    static public String Nz(String value){\r
+        return (value == null ? "" : value);\r
+    }\r
+\r
+    /**\r
+     * Returns value if value is not <code>null</code>. Returns defaultValue if value is <code>null</code>.\r
+     * @param value\r
+     * @return\r
+     */\r
+    static public String Nz(String value, String defaultValue){\r
+        return (value == null ? defaultValue : value);\r
+    }\r
+\r
+    /**\r
+     * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.\r
+     * @param value\r
+     * @return\r
+     */\r
+    static public Integer Nz(Integer value){\r
+        return (value == null ? 0 : value);\r
+    }\r
+\r
+    /**\r
+     * Returns value if value is not <code>null</code>. Returns 0 if value is <code>null</code>.\r
+     * @param value\r
+     * @return\r
+     */\r
+    static public Long Nz(Long value){\r
+        return (value == null ? 0 : value);\r
+    }\r
+\r
+    /**\r
+     * Concatenates an array of strings using the defined seperator.<BR>\r
+     * <code>Null</code> values are interpreted as empty strings.<BR>\r
+     * If all strings are <code>null</code> then <code>null</code> is returned.\r
+     * @param strings\r
+     * @param seperator\r
+     * @return String\r
+     */\r
+    static public String concat(CharSequence separator, String[] strings){\r
+        String result = "";\r
+        boolean allNull = true;\r
+        for (String string : strings){\r
+            if (string != null){\r
+                if (result.length() > 0 && string.length() > 0){\r
+                    result += separator;\r
+                }\r
+                result += string;\r
+                allNull = false;\r
+            }\r
+        }\r
+        //if all strings are null result should be null, not ""\r
+        if (allNull){\r
+            return null;\r
+        }else {\r
+            return result;\r
+        }\r
+    }\r
+\r
+    /**\r
+     * Concatenates two strings, using the defined seperator.<BR>\r
+     * <code>Null</code> values are interpreted as empty Strings.<BR>\r
+     * If both strings are <code>null</code> then <code>null</code> is returned.\r
+     * @see #concat(CharSequence, String[])\r
+     * @param seperator\r
+     * @param string1\r
+     * @param string2\r
+     * @return String\r
+     */\r
+    static public String concat(CharSequence separator, String string1, String string2){\r
+        String[] strings = {string1, string2};\r
+        return concat(separator, strings);\r
+    }\r
+\r
+\r
     /** Returns a version of the input where all contiguous\r
      * whitespace characters are replaced with a single\r
      * space. Line terminators are treated like whitespace.\r
-     * \r
+     *\r
      * @param inputStr\r
      * @return\r
      */\r
     public static CharSequence removeDuplicateWhitespace(CharSequence inputStr) {\r
-       \r
+\r
         String patternStr = "\\s+";\r
         String replaceStr = " ";\r
         Pattern pattern = Pattern.compile(patternStr);\r
         Matcher matcher = pattern.matcher(inputStr);\r
         return matcher.replaceAll(replaceStr);\r
     }\r
-    \r
+\r
 \r
     /** Builds a list of strings by splitting an input string\r
      * with delimiters whitespace, comma, or semicolon\r
@@ -262,192 +273,192 @@ public class CdmUtils {
      */\r
     public static ArrayList<String> buildList(String value) {\r
 \r
-       ArrayList<String> resultList = new ArrayList<String>();\r
-       for (String tag : value.split("[\\s,;]+")) {\r
-               resultList.add(tag);\r
-       }\r
+        ArrayList<String> resultList = new ArrayList<String>();\r
+        for (String tag : value.split("[\\s,;]+")) {\r
+            resultList.add(tag);\r
+        }\r
         return resultList;\r
     }\r
-    \r
-\r
-       static public boolean urlExists(String strUrl, boolean withWarning){\r
-               try {\r
-                    HttpURLConnection.setFollowRedirects(false);\r
-                     // note : you may also need\r
-                     //        HttpURLConnection.setInstanceFollowRedirects(false)\r
-                     HttpURLConnection con =\r
-                        (HttpURLConnection) new URL(strUrl).openConnection();\r
-                     con.setRequestMethod("HEAD");\r
-                     return (con.getResponseCode() == HttpURLConnection.HTTP_OK);\r
-               } catch (MalformedURLException e) {\r
-                       if (withWarning) {\r
-                               logger.warn(e);\r
-                       }\r
-               } catch (IOException e) {\r
-                       //\r
-               };\r
-               return false;\r
-       }\r
-       \r
-       static public URI string2Uri(String string) {\r
+\r
+\r
+    static public boolean urlExists(String strUrl, boolean withWarning){\r
+        try {\r
+             HttpURLConnection.setFollowRedirects(false);\r
+              // note : you may also need\r
+              //        HttpURLConnection.setInstanceFollowRedirects(false)\r
+              HttpURLConnection con =\r
+                 (HttpURLConnection) new URL(strUrl).openConnection();\r
+              con.setRequestMethod("HEAD");\r
+              return (con.getResponseCode() == HttpURLConnection.HTTP_OK);\r
+        } catch (MalformedURLException e) {\r
+            if (withWarning) {\r
+                logger.warn(e);\r
+            }\r
+        } catch (IOException e) {\r
+            //\r
+        };\r
+        return false;\r
+    }\r
+\r
+    static public URI string2Uri(String string) {\r
         URI uri = null;\r
-               try {\r
-                       uri = new URI(string);\r
-                       logger.debug("uri: " + uri.toString());\r
-               } catch (URISyntaxException ex) {\r
-                       logger.error("Problem converting string " + string + " to URI " + uri);\r
-                       return null;\r
-               }\r
-               return uri;\r
-       }\r
-       \r
-       static public boolean isNumeric(String string){\r
-               if (string == null){\r
-                       return false;\r
-               }\r
-               try {\r
-                       Double.valueOf(string);\r
-                       return true;\r
-               } catch (NumberFormatException e) {\r
-                       return false;\r
-               }\r
-               \r
-       }\r
-       \r
-       /**\r
-        * Returns true if the passed string starts with an upper case letter.\r
-        * @param string\r
-        * @return\r
-        */\r
-       static public boolean isCapital(String string){\r
-               if (isEmpty(string)){\r
-                       return false;\r
-               }else{\r
-                       Character firstChar = string.charAt(0);\r
-                       if (firstChar.equals(Character.toUpperCase(firstChar))){\r
-                               return true;\r
-                       }else{\r
-                               return false;\r
-                       }\r
-               }\r
-               \r
-       }\r
-\r
-       /**\r
-        * Returns true if string is null, "" or string.trim() is ""\r
-        * @see isNotEmpty(String string)\r
-        * @param string\r
-        * @return\r
-        */\r
-       static public boolean isEmpty(String string){\r
-               if (string == null){\r
-                       return true;\r
-               }\r
-               if ("".equals(string.trim())){\r
-                       return true;\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       /**\r
-        * Tests if two objects are equal or both null. Otherwise returns false\r
-        * @param obj1\r
-        * @param obj2\r
-        * @return\r
-        */\r
-       public static boolean nullSafeEqual(Object obj1, Object obj2) {\r
-               if (obj1 == null && obj2 == null){\r
-                       return true;\r
-               }\r
-               if (obj1 == null && obj2 != null){\r
-                       return false;\r
-               }\r
-               return (obj1.equals(obj2));\r
-       }\r
-       \r
-       /**\r
-        * Returns false if string is null, "" or string.trim() is ""\r
-        * Else true.\r
-        * @see isEmpty(String string)\r
-        * @param string\r
-        * @return\r
-        */\r
-       static public boolean isNotEmpty(String string){\r
-               return !isEmpty(string);\r
-       }\r
-       \r
-\r
-       /**\r
-        * Computes all fields recursively\r
-        * @param clazz\r
-        * @return\r
-        */\r
-       public static Map<String, Field> getAllFields(Class clazz, Class highestClass, boolean includeStatic, boolean includeTransient, boolean makeAccessible, boolean includeHighestClass) {\r
-               Map<String, Field> result = new HashMap<String, Field>();\r
-               if ( highestClass.isAssignableFrom(clazz) && (clazz != highestClass || includeHighestClass)){\r
-                       //exclude static\r
-                       for (Field field: clazz.getDeclaredFields()){\r
-                               if (includeStatic || ! Modifier.isStatic(field.getModifiers())){\r
-                                       if (includeTransient || ! isTransient(field)){\r
-                                               field.setAccessible(makeAccessible);\r
-                                               result.put(field.getName(), field);\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       //include superclass fields\r
-                       Class superclass = clazz.getSuperclass();\r
-                       if (superclass != null){\r
-                               result.putAll(getAllFields(superclass, highestClass, includeStatic, includeTransient, makeAccessible, includeHighestClass));\r
-                       }\r
-               }\r
-               return result;\r
-       }\r
-       \r
-\r
-       /**\r
-        * Returns true, if field has an annotation of type javax.persistence.Annotation\r
-        * @param field\r
-        * @return\r
-        */\r
-       protected static boolean isTransient(Field field) {\r
-               for (Annotation annotation : field.getAnnotations()){\r
-                       //if (Transient.class.isAssignableFrom(annotation.annotationType())){\r
-                       if (annotation.annotationType().getSimpleName().equals("Transient")){\r
-                               return true;\r
-                       }\r
-               }\r
-               return false;\r
-       }\r
-       \r
-       /**\r
-        * Trims the string and if the string ends with a dot removes it.\r
-        * @param string\r
-        * @return\r
-        */\r
-       public static String removeTrailingDot(String string){\r
-               if (string == null){\r
-                       return null;\r
-               }\r
-               if (string.trim().endsWith(".")){\r
-                       return string.substring(0, string.length() -1);\r
-               }\r
-               return string;\r
-       }\r
-\r
-       /**\r
-        * Returns surrounding brackets "(",")". Trim the string if necessary.\r
-        * @param text\r
-        * @return\r
-        */\r
-       public static String removeBrackets(String text) {\r
-               if (text == null){\r
-                       return null;\r
-               }\r
-               text = text.trim();\r
-               if (text.matches("^\\(.*\\)$")){\r
-                       text = text.substring(1, text.length() -1);\r
-               }\r
-               return text;\r
-       }\r
+        try {\r
+            uri = new URI(string);\r
+            logger.debug("uri: " + uri.toString());\r
+        } catch (URISyntaxException ex) {\r
+            logger.error("Problem converting string " + string + " to URI " + uri);\r
+            return null;\r
+        }\r
+        return uri;\r
+    }\r
+\r
+    static public boolean isNumeric(String string){\r
+        if (string == null){\r
+            return false;\r
+        }\r
+        try {\r
+            Double.valueOf(string);\r
+            return true;\r
+        } catch (NumberFormatException e) {\r
+            return false;\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Returns true if the passed string starts with an upper case letter.\r
+     * @param string\r
+     * @return\r
+     */\r
+    static public boolean isCapital(String string){\r
+        if (isEmpty(string)){\r
+            return false;\r
+        }else{\r
+            Character firstChar = string.charAt(0);\r
+            if (firstChar.equals(Character.toUpperCase(firstChar))){\r
+                return true;\r
+            }else{\r
+                return false;\r
+            }\r
+        }\r
+\r
+    }\r
+\r
+    /**\r
+     * Returns true if string is null, "" or string.trim() is ""\r
+     * @see isNotEmpty(String string)\r
+     * @param string\r
+     * @return\r
+     */\r
+    static public boolean isEmpty(String string){\r
+        if (string == null){\r
+            return true;\r
+        }\r
+        if ("".equals(string.trim())){\r
+            return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Tests if two objects are equal or both null. Otherwise returns false\r
+     * @param obj1\r
+     * @param obj2\r
+     * @return\r
+     */\r
+    public static boolean nullSafeEqual(Object obj1, Object obj2) {\r
+        if (obj1 == null && obj2 == null){\r
+            return true;\r
+        }\r
+        if (obj1 == null && obj2 != null){\r
+            return false;\r
+        }\r
+        return (obj1.equals(obj2));\r
+    }\r
+\r
+    /**\r
+     * Returns false if string is null, "" or string.trim() is ""\r
+     * Else true.\r
+     * @see isEmpty(String string)\r
+     * @param string\r
+     * @return\r
+     */\r
+    static public boolean isNotEmpty(String string){\r
+        return !isEmpty(string);\r
+    }\r
+\r
+\r
+    /**\r
+     * Computes all fields recursively\r
+     * @param clazz\r
+     * @return\r
+     */\r
+    public static Map<String, Field> getAllFields(Class clazz, Class highestClass, boolean includeStatic, boolean includeTransient, boolean makeAccessible, boolean includeHighestClass) {\r
+        Map<String, Field> result = new HashMap<String, Field>();\r
+        if ( highestClass.isAssignableFrom(clazz) && (clazz != highestClass || includeHighestClass)){\r
+            //exclude static\r
+            for (Field field: clazz.getDeclaredFields()){\r
+                if (includeStatic || ! Modifier.isStatic(field.getModifiers())){\r
+                    if (includeTransient || ! isTransient(field)){\r
+                        field.setAccessible(makeAccessible);\r
+                        result.put(field.getName(), field);\r
+                    }\r
+                }\r
+            }\r
+\r
+            //include superclass fields\r
+            Class superclass = clazz.getSuperclass();\r
+            if (superclass != null){\r
+                result.putAll(getAllFields(superclass, highestClass, includeStatic, includeTransient, makeAccessible, includeHighestClass));\r
+            }\r
+        }\r
+        return result;\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns true, if field has an annotation of type javax.persistence.Annotation\r
+     * @param field\r
+     * @return\r
+     */\r
+    protected static boolean isTransient(Field field) {\r
+        for (Annotation annotation : field.getAnnotations()){\r
+            //if (Transient.class.isAssignableFrom(annotation.annotationType())){\r
+            if (annotation.annotationType().getSimpleName().equals("Transient")){\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    }\r
+\r
+    /**\r
+     * Trims the string and if the string ends with a dot removes it.\r
+     * @param string\r
+     * @return\r
+     */\r
+    public static String removeTrailingDot(String string){\r
+        if (string == null){\r
+            return null;\r
+        }\r
+        if (string.trim().endsWith(".")){\r
+            return string.substring(0, string.length() -1);\r
+        }\r
+        return string;\r
+    }\r
+\r
+    /**\r
+     * Returns surrounding brackets "(",")". Trim the string if necessary.\r
+     * @param text\r
+     * @return\r
+     */\r
+    public static String removeBrackets(String text) {\r
+        if (text == null){\r
+            return null;\r
+        }\r
+        text = text.trim();\r
+        if (text.matches("^\\(.*\\)$")){\r
+            text = text.substring(1, text.length() -1);\r
+        }\r
+        return text;\r
+    }\r
 }
\ No newline at end of file
index a351b6d640af7216521a5825aeffb9032f88c3d7..4d8a8cca12f84190febde3de8dbe23058b89cbe7 100644 (file)
@@ -1,19 +1,19 @@
 <?xml version="1.0" encoding="UTF-8"?>\r
 <beans xmlns="http://www.springframework.org/schema/beans"\r
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
-       xmlns:context="http://www.springframework.org/schema/context"\r
-       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+  xmlns:context="http://www.springframework.org/schema/context"\r
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context
     http://www.springframework.org/schema/context/spring-context-2.5.xsd">
 \r
-    <import resource="classpath:/eu/etaxonomy/cdm/defaultApplicationContext.xml"/> \r
+    <import resource="classpath:/eu/etaxonomy/cdm/defaultApplicationContext.xml"/>\r
 \r
-       <context:component-scan base-package="eu/etaxonomy/cdm/ext"/>\r
+  <context:component-scan base-package="eu/etaxonomy/cdm/ext"/>\r
 
     <bean id="dataSource" class="org.unitils.database.UnitilsDataSourceFactoryBean"/>\r
-    \r
-    <bean id="hibernateProperties" \r
+\r
+    <bean id="hibernateProperties"\r
         class="org.springframework.beans.factory.config.PropertiesFactoryBean">\r
         <property name="properties">\r
             <props>\r
@@ -25,8 +25,8 @@
                 <prop key="hibernate.search.default.indexBase">./target/test-classes</prop>\r
             </props>\r
         </property>\r
-    </bean> \r
-    \r
+    </bean>\r
+\r
     <bean id="taxonSpellingDirectory" class="org.springmodules.lucene.index.support.FSDirectoryFactoryBean">\r
       <property name="location" value="file:./target/test-classes/eu.etaxonomy.cdm.model.taxon.TaxonBase_spelling"/>\r
       <property name="create" value="true"/>\r
@@ -39,7 +39,7 @@
         <bean class="org.apache.lucene.analysis.SimpleAnalyzer"/>\r
       </property>\r
     </bean>\r
-    \r
+\r
     <bean id="authenticationManager" class="org.springframework.security.authentication.ProviderManager">\r
         <property name="providers">\r
             <list>\r
             </list>\r
         </property>\r
     </bean>\r
-    \r
+\r
     <bean id="passwordEncoder" class="org.springframework.security.authentication.encoding.Md5PasswordEncoder"/>\r
-    \r
+\r
     <bean id="saltSource" class="org.springframework.security.authentication.dao.ReflectionSaltSource">\r
         <property name="userPropertyToUse" value="getUsername"/>\r
     </bean>
-    
+
 </beans>
\ No newline at end of file
diff --git a/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AnnotationTypeAutoInitializer.java b/cdmlib-persistence/src/main/java/eu/etaxonomy/cdm/persistence/dao/AnnotationTypeAutoInitializer.java
new file mode 100644 (file)
index 0000000..de051e5
--- /dev/null
@@ -0,0 +1,34 @@
+// $Id$\r
+/**\r
+* Copyright (C) 2009 EDIT\r
+* European Distributed Institute of Taxonomy\r
+* http://www.e-taxonomy.eu\r
+*\r
+* The contents of this file are subject to the Mozilla Public License Version 1.1\r
+* See LICENSE.TXT at the top of this package for the full license terms.\r
+*/\r
+package eu.etaxonomy.cdm.persistence.dao;\r
+\r
+import java.util.ArrayList;\r
+import java.util.Arrays;\r
+\r
+import eu.etaxonomy.cdm.model.common.Annotation;\r
+import eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer;\r
+\r
+/**\r
+ * @author a.kohlbecker\r
+ * @date 30.07.2010\r
+ *\r
+ */\r
+public class AnnotationTypeAutoInitializer extends AutoPropertyInitializer<Annotation> {\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.BeanAutoInitializer#initialize(eu.etaxonomy.cdm.model.common.CdmBase)\r
+     */\r
+    @Override\r
+    public void initialize(Annotation bean) {\r
+        beanInitializer.initialize(bean, Arrays.asList(new String[] {"annotationType"}));\r
+    }\r
+\r
+}\r
index f6d40373c84e5fd5e95bfc59453a8f53e1a3495f..430cc0a92a12ae340b18a8bcf2cce68b6a0a7de4 100644 (file)
@@ -1,14 +1,16 @@
 // $Id$\r
 /**\r
 * Copyright (C) 2009 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
 package eu.etaxonomy.cdm.persistence.dao;\r
 \r
+import org.springframework.beans.factory.annotation.Autowired;\r
+\r
 import eu.etaxonomy.cdm.model.common.CdmBase;\r
 \r
 /**\r
@@ -17,7 +19,11 @@ import eu.etaxonomy.cdm.model.common.CdmBase;
  *\r
  */\r
 public abstract class AutoPropertyInitializer<T extends CdmBase> {\r
-       \r
-       public abstract void initialize(T bean); \r
+\r
+    @Autowired\r
+    protected BeanInitializer beanInitializer;\r
+\r
+\r
+    public abstract void initialize(T bean);\r
 \r
 }\r
index 05462a2a6a0f171c5f79a97da15559fe4bdf89fc..3b55f5eb860021b088bac92cc857878b1fefaf85 100644 (file)
@@ -1,8 +1,8 @@
 /**
 * Copyright (C) 2007 EDIT
-* European Distributed Institute of Taxonomy 
+* European Distributed Institute of Taxonomy
 * http://www.e-taxonomy.eu
-* 
+*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * See LICENSE.TXT at the top of this package for the full license terms.
 */
@@ -23,43 +23,43 @@ import org.springframework.beans.factory.annotation.Autowired;
 import eu.etaxonomy.cdm.persistence.query.OrderHint;
 
 public abstract class DaoBase {
-       
-       @Autowired
-       private SessionFactory factory;
-       
-       public void setSessionFactory(SessionFactory sessionFactory) {
-               this.factory = sessionFactory;
-       }
-       public SessionFactory getSessionFactory() {
-               return factory;
-       }
-       protected Session getSession(){
-               Session session = factory.getCurrentSession();
-               return session;
-       }
-       
-       public void flush(){
-               getSession().flush();
-       }
-       
-       private class OrderHintComparator implements Comparator<OrderHint> {
 
-               public int compare(OrderHint o1, OrderHint o2) {
-                       return o1.getPropertyName().compareTo(o2.getPropertyName());
-               }
-               
-       }
-       
-       protected void addOrder(Criteria criteria, List<OrderHint> orderHints) {
-               
-               if(orderHints != null){
-                       Collections.sort(orderHints, new OrderHintComparator());
-                       
-                       Map<String,Criteria> criteriaMap = new HashMap<String,Criteria>();
-                       for(OrderHint orderHint : orderHints){
-                               orderHint.add(criteria,criteriaMap);
-                       }
-               }
-       }
+    @Autowired
+    private SessionFactory factory;
+
+    public void setSessionFactory(SessionFactory sessionFactory) {
+        this.factory = sessionFactory;
+    }
+    public SessionFactory getSessionFactory() {
+        return factory;
+    }
+    protected Session getSession(){
+        Session session = factory.getCurrentSession();
+        return session;
+    }
+
+    public void flush(){
+        getSession().flush();
+    }
+
+    private class OrderHintComparator implements Comparator<OrderHint> {
+
+        public int compare(OrderHint o1, OrderHint o2) {
+            return o1.getPropertyName().compareTo(o2.getPropertyName());
+        }
+
+    }
+
+    protected void addOrder(Criteria criteria, List<OrderHint> orderHints) {
+
+        if(orderHints != null){
+            Collections.sort(orderHints, new OrderHintComparator());
+
+            Map<String,Criteria> criteriaMap = new HashMap<String,Criteria>();
+            for(OrderHint orderHint : orderHints){
+                orderHint.add(criteria,criteriaMap);
+            }
+        }
+    }
 
 }
index 5e429b9a7e335f091a49e5e57ef4608b43f0d641..ff127730dcc11a0e5396bbf3277f91f986deec42 100644 (file)
@@ -1,8 +1,8 @@
 /**\r
  * Copyright (C) 2007 EDIT\r
- * European Distributed Institute of Taxonomy \r
+ * European Distributed Institute of Taxonomy\r
  * http://www.e-taxonomy.eu\r
- * \r
+ *\r
  * The contents of this file are subject to the Mozilla Public License Version 1.1\r
  * See LICENSE.TXT at the top of this package for the full license terms.\r
  */\r
@@ -83,696 +83,696 @@ import eu.etaxonomy.cdm.persistence.query.OrderHint.SortOrder;
  */\r
 @Repository\r
 @Qualifier("taxonDaoHibernateImpl")\r
-public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {       \r
-       private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;\r
-       private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\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_tokenized";\r
-       }\r
-       \r
-       @Autowired\r
-       private ITaxonNameDao taxonNameDao;\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
-       }\r
-       \r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)\r
-        */\r
-       public List<Taxon> getRootTaxa(Reference sec) {\r
-               return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);\r
-       }\r
-               \r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
-        */\r
-       public List<Taxon> getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");\r
-               if (onlyWithChildren == null){\r
-                       onlyWithChildren = true;\r
-               }\r
-               if (withMisapplications == null){\r
-                       withMisapplications = true;\r
-               }\r
-               if (cdmFetch == null){\r
-                       cdmFetch = CdmFetch.NO_FETCH();\r
-               }\r
-\r
-               Criteria crit = getSession().createCriteria(Taxon.class);\r
-               \r
-               crit.setFetchMode("name", FetchMode.JOIN);\r
-               crit.createAlias("name", "name");\r
-               \r
-               if (rank != null) {\r
-                       crit.add(Restrictions.eq("name.rank", rank));\r
-               }else{\r
-                       crit.add(Restrictions.isNull("taxonomicParentCache"));\r
-               }\r
-\r
-               if (sec != null){\r
-                       crit.add(Restrictions.eq("sec", sec) );\r
-               }\r
-\r
-               if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){\r
-                       logger.info("Not fetching child taxa");\r
-                       //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)\r
-                       crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);\r
-               }\r
-\r
-               List<Taxon> results = new ArrayList<Taxon>();\r
-               List<Taxon> taxa = crit.list();\r
-               for(Taxon taxon : taxa){\r
-                       \r
-                       \r
-                       //childTaxa\r
-                       //TODO create restriction instead\r
-                       // (a) not using cache fields\r
-                       /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());\r
-                       if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){\r
-                               if (withMisapplications == true || ! taxon.isMisappliedName()){\r
-                                       defaultBeanInitializer.initialize(taxon, propertyPaths);\r
-                                       results.add(taxon);\r
-                               }\r
-                       }*/\r
-                       // (b) using cache fields\r
-                       if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){\r
-                               if (withMisapplications == true || ! taxon.isMisapplication()){\r
-                                       defaultBeanInitializer.initialize(taxon, propertyPaths);\r
-                                       results.add(taxon);\r
-                               }\r
-                       }\r
-               }\r
-               return results;\r
-       }\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
-        */\r
-       public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
-               return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.model.reference.Reference)\r
-        */\r
-       public List<TaxonBase> getTaxaByName(String queryString, Reference sec) {\r
-               \r
-               return getTaxaByName(queryString, true, sec);\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, java.lang.Boolean, eu.etaxonomy.cdm.model.reference.Reference)\r
-        */\r
-       public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, Reference sec) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, Reference sec)");\r
-               \r
+public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implements ITaxonDao {\r
+    private AlternativeSpellingSuggestionParser<TaxonBase> alternativeSpellingSuggestionParser;\r
+    private static final Logger logger = Logger.getLogger(TaxonDaoHibernateImpl.class);\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_tokenized";\r
+    }\r
+\r
+    @Autowired\r
+    private ITaxonNameDao taxonNameDao;\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
+    }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference)\r
+     */\r
+    public List<Taxon> getRootTaxa(Reference sec) {\r
+        return getRootTaxa(sec, CdmFetch.FETCH_CHILDTAXA(), true, false);\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.name.Rank, eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
+     */\r
+    public List<Taxon> getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications, List<String> propertyPaths) {\r
+        checkNotInPriorView("TaxonDaoHibernateImpl.getRootTaxa(Rank rank, Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications)");\r
+        if (onlyWithChildren == null){\r
+            onlyWithChildren = true;\r
+        }\r
+        if (withMisapplications == null){\r
+            withMisapplications = true;\r
+        }\r
+        if (cdmFetch == null){\r
+            cdmFetch = CdmFetch.NO_FETCH();\r
+        }\r
+\r
+        Criteria crit = getSession().createCriteria(Taxon.class);\r
+\r
+        crit.setFetchMode("name", FetchMode.JOIN);\r
+        crit.createAlias("name", "name");\r
+\r
+        if (rank != null) {\r
+            crit.add(Restrictions.eq("name.rank", rank));\r
+        }else{\r
+            crit.add(Restrictions.isNull("taxonomicParentCache"));\r
+        }\r
+\r
+        if (sec != null){\r
+            crit.add(Restrictions.eq("sec", sec) );\r
+        }\r
+\r
+        if (! cdmFetch.includes(CdmFetch.FETCH_CHILDTAXA())){\r
+            logger.info("Not fetching child taxa");\r
+            //TODO overwrite LAZY (SELECT) does not work (bug in hibernate?)\r
+            crit.setFetchMode("relationsToThisTaxon.fromTaxon", FetchMode.LAZY);\r
+        }\r
+\r
+        List<Taxon> results = new ArrayList<Taxon>();\r
+        List<Taxon> taxa = crit.list();\r
+        for(Taxon taxon : taxa){\r
+\r
+\r
+            //childTaxa\r
+            //TODO create restriction instead\r
+            // (a) not using cache fields\r
+            /*Hibernate.initialize(taxon.getRelationsFromThisTaxon());\r
+            if (onlyWithChildren == false || taxon.getRelationsFromThisTaxon().size() > 0){\r
+                if (withMisapplications == true || ! taxon.isMisappliedName()){\r
+                    defaultBeanInitializer.initialize(taxon, propertyPaths);\r
+                    results.add(taxon);\r
+                }\r
+            }*/\r
+            // (b) using cache fields\r
+            if (onlyWithChildren == false || taxon.hasTaxonomicChildren()){\r
+                if (withMisapplications == true || ! taxon.isMisapplication()){\r
+                    defaultBeanInitializer.initialize(taxon, propertyPaths);\r
+                    results.add(taxon);\r
+                }\r
+            }\r
+        }\r
+        return results;\r
+    }\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getRootTaxa(eu.etaxonomy.cdm.model.reference.Reference, eu.etaxonomy.cdm.persistence.fetch.CdmFetch, java.lang.Boolean, java.lang.Boolean)\r
+     */\r
+    public List<Taxon> getRootTaxa(Reference sec, CdmFetch cdmFetch, Boolean onlyWithChildren, Boolean withMisapplications) {\r
+        return getRootTaxa(null, sec, cdmFetch, onlyWithChildren, withMisapplications, null);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.model.reference.Reference)\r
+     */\r
+    public List<TaxonBase> getTaxaByName(String queryString, Reference sec) {\r
+\r
+        return getTaxaByName(queryString, true, sec);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, java.lang.Boolean, eu.etaxonomy.cdm.model.reference.Reference)\r
+     */\r
+    public List<TaxonBase> getTaxaByName(String queryString, Boolean accepted, Reference sec) {\r
+        checkNotInPriorView("TaxonDaoHibernateImpl.getTaxaByName(String name, Reference sec)");\r
+\r
         Criteria criteria = null;\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 && sec.getId() != 0) {\r
-                       criteria.add(Restrictions.eq("sec", sec ) );\r
-               }\r
-\r
-               if (queryString != null) {\r
-                       criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
-               }\r
-\r
-               return (List<TaxonBase>)criteria.list();\r
-       }\r
-\r
-       public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, MatchMode matchMode,\r
-                       Integer pageSize, Integer pageNumber) {\r
-               \r
-               return getTaxaByName(clazz, queryString, null, matchMode, null, pageSize, pageNumber, null);\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.lang.Boolean, java.lang.Integer, java.lang.Integer)\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(Taxon.class, queryString, matchMode, pageSize, pageNumber);\r
-               } else {\r
-                       return getTaxaByName(Synonym.class, queryString, matchMode, pageSize, pageNumber);\r
-               }\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
-        */\r
-       public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, \r
-                       Integer pageNumber, List<String> propertyPaths) {\r
-                               \r
-               boolean doCount = false;\r
-                       \r
-               Query query = prepareTaxaByName(clazz, "nameCache", queryString, classification, matchMode, namedAreas, pageSize, pageNumber, doCount);\r
-               \r
-               if (query != null){\r
-                       List<TaxonBase> results = query.list();\r
-                       \r
-                       defaultBeanInitializer.initializeAll(results, propertyPaths);\r
-                       //TaxonComparatorSearch comp = new TaxonComparatorSearch();\r
-                       //Collections.sort(results, comp);\r
-                       return results;\r
-               }\r
-               \r
-               return new ArrayList<TaxonBase>();\r
-               \r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
-        */\r
-       //new search for the editor, for performance issues the return values are only uuid and titleCache, to avoid the initialisation of all objects\r
-       @SuppressWarnings("unchecked")\r
-       public List<UuidAndTitleCache<TaxonBase>> getTaxaByNameForEditor(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas) {\r
-               long zstVorher;\r
-               long zstNachher;\r
-                               \r
-               boolean doCount = false;\r
-               Query query = prepareTaxaByNameForEditor(clazz, "nameCache", queryString, classification, matchMode, namedAreas, doCount);\r
-               \r
-               \r
-               if (query != null){\r
-                       List<Object[]> results = query.list();\r
-                       \r
-                       List<UuidAndTitleCache<TaxonBase>> resultObjects = new ArrayList<UuidAndTitleCache<TaxonBase>>();\r
-                       Object[] result;\r
-                       for(int i = 0; i<results.size();i++){\r
-                               result = results.get(i);\r
-                               \r
-                               //differentiate taxa and synonyms\r
-                               if (clazz.equals(Taxon.class)){\r
-                                               resultObjects.add( new UuidAndTitleCache(Taxon.class, (UUID) result[0], (String)result[1]));\r
-                               }else if (clazz.equals(Synonym.class)){\r
-                                       resultObjects.add( new UuidAndTitleCache(Synonym.class, (UUID) result[0], (String)result[1]));\r
-                               } else{\r
-                                       if (result[2].equals("synonym")) {\r
-                                               resultObjects.add( new UuidAndTitleCache(Synonym.class, (UUID) result[0], (String)result[1]));\r
-                                       }\r
-                                       else {\r
-                                               resultObjects.add( new UuidAndTitleCache(Taxon.class, (UUID) result[0], (String)result[1]));\r
-                                       }\r
-                               }\r
-                       }\r
-                       \r
-                       return resultObjects;\r
-                       \r
-               }\r
-               return new ArrayList<UuidAndTitleCache<TaxonBase>>();\r
-               \r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByCommonName(java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
-        */\r
-       public List<TaxonBase> getTaxaByCommonName(String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, \r
-                       Integer pageNumber, List<String> propertyPaths) {\r
-                       boolean doCount = false;        \r
-                       Query query = prepareTaxaByCommonName(queryString, classification, 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
-       }\r
-       \r
-       /**\r
-        * @param clazz\r
-        * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>\r
-        * @param queryString\r
-        * @param classification TODO\r
-        * @param matchMode\r
-        * @param namedAreas\r
-        * @param pageSize\r
-        * @param pageNumber\r
-        * @param doCount\r
-        * @return\r
-        * \r
-        *\r
-        */\r
-       private Query prepareTaxaByNameForEditor(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, boolean doCount) {\r
-               return prepareQuery(clazz, searchField, queryString, classification,\r
-                               matchMode, namedAreas, doCount, true);\r
-       }\r
-       \r
-       /**\r
-        * @param clazz\r
-        * @param searchField\r
-        * @param queryString\r
-        * @param classification\r
-        * @param matchMode\r
-        * @param namedAreas\r
-        * @param doCount\r
-        * @param doNotReturnFullEntities\r
-        *            if set true the seach method will not return synonym and taxon\r
-        *            entities but an array containing the uuid, titleCache, and the\r
-        *            DTYPE in lowercase letters.\r
-        * @return\r
-        */\r
-       private Query prepareQuery(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, boolean doCount, boolean doNotReturnFullEntities){\r
-               \r
-               String hqlQueryString = matchMode.queryStringFrom(queryString);\r
-               String selectWhat;\r
-               if (doNotReturnFullEntities){\r
-                       selectWhat = "t.uuid, t.titleCache ";\r
-               }else {\r
-                       selectWhat = (doCount ? "count(t)": "t");\r
-               }\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(classification != null){\r
-                       \r
-                       if(doAreaRestriction){\r
-                               \r
-                               taxonSubselect = "select t.id 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.classification = :classification" +\r
-                                       " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";\r
-                               \r
-                               \r
-                               synonymSubselect = "select s.id 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.classification = :classification" +\r
-                                       " AND sn." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                               \r
-                       } else {\r
-                               \r
-                               taxonSubselect = "select t.id from" +\r
-                                       " Taxon t" +\r
-                                       " join t.name n " +\r
-                                       " join t.taxonNodes as tn "+\r
-                                       " where" +\r
-                                       " tn.classification = :classification" +\r
-                                       " AND n." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                               \r
-                               synonymSubselect = "select s.id 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.classification = :classification" +\r
-                                       " AND sn." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                       }       \r
-               } else {\r
-                       \r
-                       if(doAreaRestriction){\r
-                               \r
-                               taxonSubselect = "select t.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                               \r
-                               synonymSubselect = "select s.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                               \r
-                       } else {\r
-                               \r
-                               taxonSubselect = "select t.id from " +\r
-                                       " Taxon t" +\r
-                                       " join t.name n "+\r
-                                       " where" +\r
-                                       " n." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-\r
-                               synonymSubselect = "select s.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
-                       }\r
-                       \r
-               }\r
-               \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(classification != null){\r
-                               subTaxon.setParameter("classification", classification);\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(classification != null){\r
-                               subSynonym.setParameter("classification", classification);\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(classification != null){\r
-                               subTaxon.setParameter("classification", classification);\r
-                               subSynonym.setParameter("classification", classification);\r
-                       }\r
-               }\r
-               \r
-               List<Integer> taxa = new ArrayList<Integer>();\r
-               List<Integer> synonyms = new ArrayList<Integer>();\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
-                               if (doNotReturnFullEntities){\r
-                                       hql = "select " + selectWhat + ", 'taxon' from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";\r
-                               }else{\r
-                                       hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";\r
-                               }\r
-                       }else{\r
-                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
-                       }\r
-               } else if(clazz.equals(Synonym.class) ){\r
-                       if (synonyms.size()>0){\r
-                               if (doNotReturnFullEntities){\r
-                                       hql = "select " + selectWhat + ", 'synonym' from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";\r
-                               }else{\r
-                                       hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";          \r
-                               }\r
-                       }else{\r
-                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
-                       }\r
-               } else {\r
-                       \r
-                       if(synonyms.size()>0 && taxa.size()>0){\r
-                               if (doNotReturnFullEntities &&  !doCount ){\r
-                                       // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
-                                       hql = "select " + selectWhat + ", case when t.id in (:taxa) then 'taxon' else 'synonym' end" + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";\r
-                               }else{\r
-                                       hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";\r
-                               }\r
-                       }else if (synonyms.size()>0 ){\r
-                               if (doNotReturnFullEntities &&  !doCount ){\r
-                                       // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
-                                       hql = "select " + selectWhat + ", 'synonym' from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";       \r
-                               } else {\r
-                                       hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";          \r
-                               }\r
-                       } else if (taxa.size()>0 ){\r
-                               if (doNotReturnFullEntities &&  !doCount ){\r
-                                       // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
-                                       hql = "select " + selectWhat + ", 'taxon' from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";\r
-                               } else {\r
-                                       hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";\r
-                               }\r
-                       } else{\r
-                               hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
-                       }\r
-               }\r
-               \r
-               if (hql == "") return null;\r
-               if(!doCount){\r
-                       hql += " order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";\r
-               }\r
-       \r
-               Query query = getSession().createQuery(hql);\r
-                               \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
-               return query;\r
-               \r
-       }\r
-       \r
-       \r
-       /**\r
-        * @param clazz\r
-        * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>\r
-        * @param queryString\r
-        * @param classification TODO\r
-        * @param matchMode\r
-        * @param namedAreas\r
-        * @param pageSize\r
-        * @param pageNumber\r
-        * @param doCount\r
-        * @return\r
-        * \r
-        * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}\r
-        */\r
-       private Query prepareTaxaByName(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount) {\r
-\r
-               Query query = prepareQuery(clazz, searchField, queryString, classification,     matchMode, namedAreas, doCount, false);\r
-               \r
-               if(pageSize != null &&  !doCount) {\r
-                       query.setMaxResults(pageSize);\r
-                       if(pageNumber != null) {\r
-                               query.setFirstResult(pageNumber * pageSize);\r
-                       }\r
-               }\r
-               \r
-               return query;\r
-       }\r
-\r
-       private Query prepareTaxaByCommonName(String queryString, Classification classification,\r
-                       MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount){\r
-                               \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 "+matchMode.getMatchOperator()+" :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.Reference, java.util.Set)\r
-        */\r
-       public long countTaxaByName(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
-               MatchMode matchMode, Set<NamedArea> namedAreas) {\r
-               \r
-               boolean doCount = true;\r
-               Query query = prepareTaxaByName(clazz, "nameCache", queryString, classification, matchMode, namedAreas, null, null, doCount);\r
-               if (query != null) {\r
-                       return (Long)query.uniqueResult();\r
-               }else{\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
+        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 && sec.getId() != 0) {\r
+            criteria.add(Restrictions.eq("sec", sec ) );\r
+        }\r
+\r
+        if (queryString != null) {\r
+            criteria.add(Restrictions.ilike("name.nameCache", queryString));\r
+        }\r
+\r
+        return (List<TaxonBase>)criteria.list();\r
+    }\r
+\r
+    public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, MatchMode matchMode,\r
+            Integer pageSize, Integer pageNumber) {\r
+\r
+        return getTaxaByName(clazz, queryString, null, matchMode, null, pageSize, pageNumber, null);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, java.lang.Boolean, java.lang.Integer, java.lang.Integer)\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(Taxon.class, queryString, matchMode, pageSize, pageNumber);\r
+        } else {\r
+            return getTaxaByName(Synonym.class, queryString, matchMode, pageSize, pageNumber);\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
+     */\r
+    public List<TaxonBase> getTaxaByName(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize,\r
+            Integer pageNumber, List<String> propertyPaths) {\r
+\r
+        boolean doCount = false;\r
+\r
+        Query query = prepareTaxaByName(clazz, "nameCache", queryString, classification, matchMode, namedAreas, pageSize, pageNumber, doCount);\r
+\r
+        if (query != null){\r
+            List<TaxonBase> results = query.list();\r
+\r
+            defaultBeanInitializer.initializeAll(results, propertyPaths);\r
+            //TaxonComparatorSearch comp = new TaxonComparatorSearch();\r
+            //Collections.sort(results, comp);\r
+            return results;\r
+        }\r
+\r
+        return new ArrayList<TaxonBase>();\r
+\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByName(java.lang.Class, java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
+     */\r
+    //new search for the editor, for performance issues the return values are only uuid and titleCache, to avoid the initialisation of all objects\r
+    @SuppressWarnings("unchecked")\r
+    public List<UuidAndTitleCache<TaxonBase>> getTaxaByNameForEditor(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas) {\r
+        long zstVorher;\r
+        long zstNachher;\r
+\r
+        boolean doCount = false;\r
+        Query query = prepareTaxaByNameForEditor(clazz, "nameCache", queryString, classification, matchMode, namedAreas, doCount);\r
+\r
+\r
+        if (query != null){\r
+            List<Object[]> results = query.list();\r
+\r
+            List<UuidAndTitleCache<TaxonBase>> resultObjects = new ArrayList<UuidAndTitleCache<TaxonBase>>();\r
+            Object[] result;\r
+            for(int i = 0; i<results.size();i++){\r
+                result = results.get(i);\r
+\r
+                //differentiate taxa and synonyms\r
+                if (clazz.equals(Taxon.class)){\r
+                        resultObjects.add( new UuidAndTitleCache(Taxon.class, (UUID) result[0], (String)result[1]));\r
+                }else if (clazz.equals(Synonym.class)){\r
+                    resultObjects.add( new UuidAndTitleCache(Synonym.class, (UUID) result[0], (String)result[1]));\r
+                } else{\r
+                    if (result[2].equals("synonym")) {\r
+                        resultObjects.add( new UuidAndTitleCache(Synonym.class, (UUID) result[0], (String)result[1]));\r
+                    }\r
+                    else {\r
+                        resultObjects.add( new UuidAndTitleCache(Taxon.class, (UUID) result[0], (String)result[1]));\r
+                    }\r
+                }\r
+            }\r
+\r
+            return resultObjects;\r
+\r
+        }\r
+        return new ArrayList<UuidAndTitleCache<TaxonBase>>();\r
+\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxaByCommonName(java.lang.String, eu.etaxonomy.cdm.model.taxon.Classification, eu.etaxonomy.cdm.persistence.query.MatchMode, java.util.Set, java.lang.Integer, java.lang.Integer, java.util.List)\r
+     */\r
+    public List<TaxonBase> getTaxaByCommonName(String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize,\r
+            Integer pageNumber, List<String> propertyPaths) {\r
+            boolean doCount = false;\r
+            Query query = prepareTaxaByCommonName(queryString, classification, 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
+    }\r
+\r
+    /**\r
+     * @param clazz\r
+     * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>\r
+     * @param queryString\r
+     * @param classification TODO\r
+     * @param matchMode\r
+     * @param namedAreas\r
+     * @param pageSize\r
+     * @param pageNumber\r
+     * @param doCount\r
+     * @return\r
+     *\r
+     *\r
+     */\r
+    private Query prepareTaxaByNameForEditor(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, boolean doCount) {\r
+        return prepareQuery(clazz, searchField, queryString, classification,\r
+                matchMode, namedAreas, doCount, true);\r
+    }\r
+\r
+    /**\r
+     * @param clazz\r
+     * @param searchField\r
+     * @param queryString\r
+     * @param classification\r
+     * @param matchMode\r
+     * @param namedAreas\r
+     * @param doCount\r
+     * @param doNotReturnFullEntities\r
+     *            if set true the seach method will not return synonym and taxon\r
+     *            entities but an array containing the uuid, titleCache, and the\r
+     *            DTYPE in lowercase letters.\r
+     * @return\r
+     */\r
+    private Query prepareQuery(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, boolean doCount, boolean doNotReturnFullEntities){\r
+\r
+        String hqlQueryString = matchMode.queryStringFrom(queryString);\r
+        String selectWhat;\r
+        if (doNotReturnFullEntities){\r
+            selectWhat = "t.uuid, t.titleCache ";\r
+        }else {\r
+            selectWhat = (doCount ? "count(t)": "t");\r
+        }\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(classification != null){\r
+\r
+            if(doAreaRestriction){\r
+\r
+                taxonSubselect = "select t.id 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.classification = :classification" +\r
+                    " AND n." + searchField + " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+\r
+                synonymSubselect = "select s.id 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.classification = :classification" +\r
+                    " AND sn." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+            } else {\r
+\r
+                taxonSubselect = "select t.id from" +\r
+                    " Taxon t" +\r
+                    " join t.name n " +\r
+                    " join t.taxonNodes as tn "+\r
+                    " where" +\r
+                    " tn.classification = :classification" +\r
+                    " AND n." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+                synonymSubselect = "select s.id 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.classification = :classification" +\r
+                    " AND sn." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+            }\r
+        } else {\r
+\r
+            if(doAreaRestriction){\r
+\r
+                taxonSubselect = "select t.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+                synonymSubselect = "select s.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+            } else {\r
+\r
+                taxonSubselect = "select t.id from " +\r
+                    " Taxon t" +\r
+                    " join t.name n "+\r
+                    " where" +\r
+                    " n." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+\r
+                synonymSubselect = "select s.id 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." + searchField +  " " + matchMode.getMatchOperator() + " :queryString";\r
+            }\r
+\r
+        }\r
+\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(classification != null){\r
+                subTaxon.setParameter("classification", classification);\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(classification != null){\r
+                subSynonym.setParameter("classification", classification);\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(classification != null){\r
+                subTaxon.setParameter("classification", classification);\r
+                subSynonym.setParameter("classification", classification);\r
+            }\r
+        }\r
+\r
+        List<Integer> taxa = new ArrayList<Integer>();\r
+        List<Integer> synonyms = new ArrayList<Integer>();\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
+                if (doNotReturnFullEntities){\r
+                    hql = "select " + selectWhat + ", 'taxon' from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";\r
+                }else{\r
+                    hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa)";\r
+                }\r
+            }else{\r
+                hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
+            }\r
+        } else if(clazz.equals(Synonym.class) ){\r
+            if (synonyms.size()>0){\r
+                if (doNotReturnFullEntities){\r
+                    hql = "select " + selectWhat + ", 'synonym' from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";\r
+                }else{\r
+                    hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";\r
+                }\r
+            }else{\r
+                hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
+            }\r
+        } else {\r
+\r
+            if(synonyms.size()>0 && taxa.size()>0){\r
+                if (doNotReturnFullEntities &&  !doCount ){\r
+                    // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
+                    hql = "select " + selectWhat + ", case when t.id in (:taxa) then 'taxon' else 'synonym' end" + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";\r
+                }else{\r
+                    hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) OR t.id in (:synonyms)";\r
+                }\r
+            }else if (synonyms.size()>0 ){\r
+                if (doNotReturnFullEntities &&  !doCount ){\r
+                    // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
+                    hql = "select " + selectWhat + ", 'synonym' from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";\r
+                } else {\r
+                    hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:synonyms)";\r
+                }\r
+            } else if (taxa.size()>0 ){\r
+                if (doNotReturnFullEntities &&  !doCount ){\r
+                    // in doNotReturnFullEntities mode it is nesscary to also return the type of the matching entities:\r
+                    hql = "select " + selectWhat + ", 'taxon' from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";\r
+                } else {\r
+                    hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t" + " where t.id in (:taxa) ";\r
+                }\r
+            } else{\r
+                hql = "select " + selectWhat + " from " + clazz.getSimpleName() + " t";\r
+            }\r
+        }\r
+\r
+        if (hql == "") return null;\r
+        if(!doCount){\r
+            hql += " order by t.name.genusOrUninomial, case when t.name.specificEpithet like '\"%\"' then 1 else 0 end, t.name.specificEpithet, t.name.rank desc, t.name.nameCache";\r
+        }\r
+\r
+        Query query = getSession().createQuery(hql);\r
+\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
+        return query;\r
+\r
+    }\r
+\r
+\r
+    /**\r
+     * @param clazz\r
+     * @param searchField the field in TaxonNameBase to be searched through usually either <code>nameCache</code> or <code>titleCache</code>\r
+     * @param queryString\r
+     * @param classification TODO\r
+     * @param matchMode\r
+     * @param namedAreas\r
+     * @param pageSize\r
+     * @param pageNumber\r
+     * @param doCount\r
+     * @return\r
+     *\r
+     * FIXME implement classification restriction & implement test: see {@link TaxonDaoHibernateImplTest#testCountTaxaByName()}\r
+     */\r
+    private Query prepareTaxaByName(Class<? extends TaxonBase> clazz, String searchField, String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount) {\r
+\r
+        Query query = prepareQuery(clazz, searchField, queryString, classification,    matchMode, namedAreas, doCount, false);\r
+\r
+        if(pageSize != null &&  !doCount) {\r
+            query.setMaxResults(pageSize);\r
+            if(pageNumber != null) {\r
+                query.setFirstResult(pageNumber * pageSize);\r
+            }\r
+        }\r
+\r
+        return query;\r
+    }\r
+\r
+    private Query prepareTaxaByCommonName(String queryString, Classification classification,\r
+            MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber, boolean doCount){\r
+\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 "+matchMode.getMatchOperator()+" :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.Reference, java.util.Set)\r
+     */\r
+    public long countTaxaByName(Class<? extends TaxonBase> clazz, String queryString, Classification classification,\r
+        MatchMode matchMode, Set<NamedArea> namedAreas) {\r
+\r
+        boolean doCount = true;\r
+        Query query = prepareTaxaByName(clazz, "nameCache", queryString, classification, matchMode, namedAreas, null, null, doCount);\r
+        if (query != null) {\r
+            return (Long)query.uniqueResult();\r
+        }else{\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
+//     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.Reference)\r
 //      */\r
-//     public Integer countTaxaByName(String queryString, \r
+//     public Integer countTaxaByName(String queryString,\r
 //                     MatchMode matchMode, SelectMode selectMode, Reference sec) {\r
 //\r
 //             Long count = countTaxaByName(queryString, matchMode, selectMode, sec, null);\r
 //             return count.intValue();\r
 //\r
 //     }\r
-       \r
+\r
 //     public Integer countTaxaByName(String queryString, MatchMode matchMode, Boolean accepted) {\r
-//             \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
-       public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {\r
-               return super.list(pagesize, page);\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)\r
-        */\r
-       public List<Synonym> getAllSynonyms(Integer limit, Integer 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
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)\r
-        */\r
-       public List<Taxon> getAllTaxa(Integer limit, Integer start) {\r
+\r
+    public List<TaxonBase> getAllTaxonBases(Integer pagesize, Integer page) {\r
+        return super.list(pagesize, page);\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllSynonyms(java.lang.Integer, java.lang.Integer)\r
+     */\r
+    public List<Synonym> getAllSynonyms(Integer limit, Integer 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
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllTaxa(java.lang.Integer, java.lang.Integer)\r
+     */\r
+    public List<Taxon> getAllTaxa(Integer limit, Integer 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
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)\r
-        */\r
-       @Override\r
-       public List<RelationshipBase> getAllRelationships(/*Class<? extends RelationshipBase> clazz,*/ Integer limit, Integer start) {\r
-               Class<? extends RelationshipBase> clazz = RelationshipBase.class;  //preliminary, see #2653\r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                   Criteria criteria = getSession().createCriteria(clazz);\r
-                   criteria.setFirstResult(start);\r
-                   if (limit != null){\r
-                       criteria.setMaxResults(limit);\r
-                   }\r
-                   return (List<RelationshipBase>)criteria.list();\r
-               } else {\r
-                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());\r
-                       return (List<RelationshipBase>)query.getResultList();\r
-               }\r
-       }\r
-       \r
-       /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */\r
+\r
+        if(limit != null) {\r
+            criteria.setFirstResult(start);\r
+            criteria.setMaxResults(limit);\r
+        }\r
+\r
+        return criteria.list();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getAllRelationships(java.lang.Integer, java.lang.Integer)\r
+     */\r
+    @Override\r
+    public List<RelationshipBase> getAllRelationships(/*Class<? extends RelationshipBase> clazz,*/ Integer limit, Integer start) {\r
+        Class<? extends RelationshipBase> clazz = RelationshipBase.class;  //preliminary, see #2653\r
+        AuditEvent auditEvent = getAuditEventFromContext();\r
+        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+            Criteria criteria = getSession().createCriteria(clazz);\r
+            criteria.setFirstResult(start);\r
+            if (limit != null){\r
+                criteria.setMaxResults(limit);\r
+            }\r
+            return (List<RelationshipBase>)criteria.list();\r
+        } else {\r
+            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(clazz,auditEvent.getRevisionNumber());\r
+            return (List<RelationshipBase>)query.getResultList();\r
+        }\r
+    }\r
+\r
+    /** Sets the taxonomic parent to null. Does not handle taxonomic relationships. */\r
 //     private boolean nullifyTaxonomicParent(Taxon taxon) {\r
 //\r
 //             try {\r
@@ -793,1297 +793,1297 @@ public class TaxonDaoHibernateImpl extends IdentifiableDaoBase<TaxonBase> implem
 //             }\r
 //             return true;\r
 //     }\r
-       \r
-       @Override\r
-       public UUID delete(TaxonBase taxonBase) throws DataAccessException{\r
-               if (taxonBase == null){\r
-                       logger.warn("TaxonBase was 'null'");\r
-                       return null;\r
-               }\r
-               \r
-               // Merge the object in if it is detached\r
-               //\r
-               // I think this is preferable to catching lazy initialization errors \r
-               // as that solution only swallows and hides the exception, but doesn't \r
-               // actually solve it.\r
-               getSession().merge(taxonBase);\r
-               \r
-               if (taxonBase instanceof Taxon){ //     is Taxon\r
-                       for (Iterator<TaxonRelationship> iterator = ((Taxon)taxonBase).getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
-                               TaxonRelationship relationFromThisTaxon = iterator.next();\r
-                               \r
-                               // decrease children count of taxonomic parent by one\r
-                               if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
-                                       Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent\r
-                                       if (toTaxon != null) {\r
-                                               toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);     \r
-                                       }\r
-                               }\r
-                       }\r
-               }\r
-               \r
-               return super.delete(taxonBase);\r
-       }\r
-\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)\r
-        */\r
-       public List<TaxonBase> findByNameTitleCache(Class<? extends TaxonBase>clazz, String queryString, Classification classification, MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageNumber, Integer pageSize, List<String> propertyPaths) {\r
-       \r
-               boolean doCount = false;\r
-               Query query = prepareTaxaByName(clazz, "titleCache", queryString, classification, 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
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)\r
-        */\r
-       public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");\r
-               Criteria crit = getSession().createCriteria(type);\r
-               crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));\r
-               crit.setProjection(Projections.rowCount());\r
-               int result = ((Integer)crit.list().get(0)).intValue();\r
-               return result;\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)\r
-        */\r
-       public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted, List<Criterion> criteria) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");\r
-               Criteria crit = getSession().createCriteria(type);\r
-               crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));\r
-               if(criteria != null){\r
-                       for (Criterion criterion : criteria) {\r
-                               crit.add(criterion);\r
-                       }\r
-               }\r
-               crit.setProjection(Projections.rowCount());\r
-               int result = ((Integer)crit.list().get(0)).intValue();\r
-               return result;\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)\r
-        */\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."+direction+" = :relatedTaxon");\r
-                   } else {\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
-                   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(direction.toString()).eq(taxon.getId()));\r
-                       query.addProjection(AuditEntity.id().count("id"));\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\r
-                       \r
-                       return ((Long)query.getSingleResult()).intValue();\r
-               }\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)\r
-        */\r
-       public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {\r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
-\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
-                       query.addProjection(AuditEntity.id().count("id"));\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\r
-                       \r
-                       return ((Long)query.getSingleResult()).intValue();\r
-               }\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)\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
-                       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(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\r
-                       \r
-                       return ((Long)query.getSingleResult()).intValue();\r
-               }\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank)\r
-        */\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
+\r
+    @Override\r
+    public UUID delete(TaxonBase taxonBase) throws DataAccessException{\r
+        if (taxonBase == null){\r
+            logger.warn("TaxonBase was 'null'");\r
+            return null;\r
+        }\r
+\r
+        // Merge the object in if it is detached\r
+        //\r
+        // I think this is preferable to catching lazy initialization errors\r
+        // as that solution only swallows and hides the exception, but doesn't\r
+        // actually solve it.\r
+        getSession().merge(taxonBase);\r
+\r
+        if (taxonBase instanceof Taxon){ //    is Taxon\r
+            for (Iterator<TaxonRelationship> iterator = ((Taxon)taxonBase).getRelationsFromThisTaxon().iterator(); iterator.hasNext();){\r
+                TaxonRelationship relationFromThisTaxon = iterator.next();\r
+\r
+                // decrease children count of taxonomic parent by one\r
+                if (relationFromThisTaxon.getType().equals(TaxonRelationshipType.TAXONOMICALLY_INCLUDED_IN())) {\r
+                    Taxon toTaxon = relationFromThisTaxon.getToTaxon(); // parent\r
+                    if (toTaxon != null) {\r
+                        toTaxon.setTaxonomicChildrenCount(toTaxon.getTaxonomicChildrenCount() - 1);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+\r
+        return super.delete(taxonBase);\r
+    }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, int, int, boolean)\r
+     */\r
+    public List<TaxonBase> findByNameTitleCache(Class<? extends TaxonBase>clazz, String queryString, Classification classification, MatchMode matchMode, Set<NamedArea> namedAreas, Integer pageNumber, Integer pageSize, List<String> propertyPaths) {\r
+\r
+        boolean doCount = false;\r
+        Query query = prepareTaxaByName(clazz, "titleCache", queryString, classification, 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
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean)\r
+     */\r
+    public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted) {\r
+        checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted)");\r
+        Criteria crit = getSession().createCriteria(type);\r
+        crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));\r
+        crit.setProjection(Projections.rowCount());\r
+        int result = ((Integer)crit.list().get(0)).intValue();\r
+        return result;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countMatchesByName(java.lang.String, eu.etaxonomy.cdm.persistence.query.MatchMode, boolean, java.util.List)\r
+     */\r
+    public int countMatchesByName(String queryString, MatchMode matchMode, boolean onlyAcccepted, List<Criterion> criteria) {\r
+        checkNotInPriorView("TaxonDaoHibernateImpl.countMatchesByName(String queryString, ITitledDao.MATCH_MODE matchMode, boolean onlyAcccepted, List<Criterion> criteria)");\r
+        Criteria crit = getSession().createCriteria(type);\r
+        crit.add(Restrictions.ilike("titleCache", matchMode.queryStringFrom(queryString)));\r
+        if(criteria != null){\r
+            for (Criterion criterion : criteria) {\r
+                crit.add(criterion);\r
+            }\r
+        }\r
+        crit.setProjection(Projections.rowCount());\r
+        int result = ((Integer)crit.list().get(0)).intValue();\r
+        return result;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)\r
+     */\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."+direction+" = :relatedTaxon");\r
+            } else {\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
+            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(direction.toString()).eq(taxon.getId()));\r
+            query.addProjection(AuditEntity.id().count("id"));\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\r
+\r
+            return ((Long)query.getSingleResult()).intValue();\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)\r
+     */\r
+    public int countSynonyms(Taxon taxon, SynonymRelationshipType type) {\r
+        AuditEvent auditEvent = getAuditEventFromContext();\r
+        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+            Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
+\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
+            query.addProjection(AuditEntity.id().count("id"));\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\r
+\r
+            return ((Long)query.getSingleResult()).intValue();\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType)\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
+            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(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\r
+\r
+            return ((Long)query.getSingleResult()).intValue();\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank)\r
+     */\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
-               if(clazz == null) {\r
-                       criteria = getSession().createCriteria(TaxonBase.class);\r
-               } else {\r
-                       criteria = getSession().createCriteria(clazz);          \r
-               }\r
-               \r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
-               \r
-               if(genusOrUninomial == null) {\r
-                       criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
-               } else if(!genusOrUninomial.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
-               }\r
-               \r
-               if(infraGenericEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
-               } else if(!infraGenericEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
-               } \r
-               \r
-               if(specificEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.specificEpithet"));\r
-               } else if(!specificEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
-                       \r
-               }\r
-               \r
-               if(infraSpecificEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
-               } else if(!infraSpecificEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
-               }\r
-\r
-               if(rank != null) {\r
-                       criteria.add(Restrictions.eq("name.rank", rank));\r
-               }\r
-               \r
-               criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
-       \r
-               return (Integer)criteria.uniqueResult();\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)\r
-        */\r
-       public List<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,  Integer pageNumber) {\r
-               checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,      Integer pageNumber)");\r
-               Criteria criteria = null;\r
-               \r
-               if(clazz == null) {\r
-                       criteria = getSession().createCriteria(TaxonBase.class);\r
-               } else {\r
-                       criteria = getSession().createCriteria(clazz);\r
-               }\r
-               \r
-               criteria.setFetchMode( "name", FetchMode.JOIN );\r
-               criteria.createAlias("name", "name");\r
-               \r
-               if(genusOrUninomial == null) {\r
-                       criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
-               } else if(!genusOrUninomial.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
-               }\r
-               \r
-               if(infraGenericEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
-               } else if(!infraGenericEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
-               } \r
-               \r
-               if(specificEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.specificEpithet"));\r
-               } else if(!specificEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
-                       \r
-               }\r
-               \r
-               if(infraSpecificEpithet == null) {\r
-                       criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
-               } else if(!infraSpecificEpithet.equals("*")) {\r
-                       criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
-               }\r
-               \r
-               if(rank != null) {\r
-                       criteria.add(Restrictions.eq("name.rank", rank));\r
-               }\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
-               return (List<TaxonBase>)criteria.list();\r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)\r
-        */\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
-            \r
-                       if(direction != null) {\r
-                               criteria.add(Restrictions.eq(direction.name(), taxon));                         \r
-                       }\r
-                       \r
-                   if(type != null) {\r
-                       criteria.add(Restrictions.eq("type", type));\r
-                   } \r
-               \r
+\r
+        if(clazz == null) {\r
+            criteria = getSession().createCriteria(TaxonBase.class);\r
+        } else {\r
+            criteria = getSession().createCriteria(clazz);\r
+        }\r
+\r
+        criteria.setFetchMode( "name", FetchMode.JOIN );\r
+        criteria.createAlias("name", "name");\r
+\r
+        if(genusOrUninomial == null) {\r
+            criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
+        } else if(!genusOrUninomial.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
+        }\r
+\r
+        if(infraGenericEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
+        } else if(!infraGenericEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
+        }\r
+\r
+        if(specificEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.specificEpithet"));\r
+        } else if(!specificEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
+\r
+        }\r
+\r
+        if(infraSpecificEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
+        } else if(!infraSpecificEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
+        }\r
+\r
+        if(rank != null) {\r
+            criteria.add(Restrictions.eq("name.rank", rank));\r
+        }\r
+\r
+        criteria.setProjection(Projections.projectionList().add(Projections.rowCount()));\r
+\r
+        return (Integer)criteria.uniqueResult();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#findTaxaByName(java.lang.Class, java.lang.String, java.lang.String, java.lang.String, java.lang.String, eu.etaxonomy.cdm.model.name.Rank, java.lang.Integer, java.lang.Integer)\r
+     */\r
+    public List<TaxonBase> findTaxaByName(Class<? extends TaxonBase> clazz, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,     Integer pageNumber) {\r
+        checkNotInPriorView("TaxonDaoHibernateImpl.findTaxaByName(Boolean accepted, String genusOrUninomial, String infraGenericEpithet, String specificEpithet, String infraSpecificEpithet, Rank rank, Integer pageSize,     Integer pageNumber)");\r
+        Criteria criteria = null;\r
+\r
+        if(clazz == null) {\r
+            criteria = getSession().createCriteria(TaxonBase.class);\r
+        } else {\r
+            criteria = getSession().createCriteria(clazz);\r
+        }\r
+\r
+        criteria.setFetchMode( "name", FetchMode.JOIN );\r
+        criteria.createAlias("name", "name");\r
+\r
+        if(genusOrUninomial == null) {\r
+            criteria.add(Restrictions.isNull("name.genusOrUninomial"));\r
+        } else if(!genusOrUninomial.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.genusOrUninomial", genusOrUninomial));\r
+        }\r
+\r
+        if(infraGenericEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.infraGenericEpithet"));\r
+        } else if(!infraGenericEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.infraGenericEpithet", infraGenericEpithet));\r
+        }\r
+\r
+        if(specificEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.specificEpithet"));\r
+        } else if(!specificEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.specificEpithet", specificEpithet));\r
+\r
+        }\r
+\r
+        if(infraSpecificEpithet == null) {\r
+            criteria.add(Restrictions.isNull("name.infraSpecificEpithet"));\r
+        } else if(!infraSpecificEpithet.equals("*")) {\r
+            criteria.add(Restrictions.eq("name.infraSpecificEpithet", infraSpecificEpithet));\r
+        }\r
+\r
+        if(rank != null) {\r
+            criteria.add(Restrictions.eq("name.rank", rank));\r
+        }\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
+        return (List<TaxonBase>)criteria.list();\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getTaxonRelationships(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.TaxonRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction)\r
+     */\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
+\r
+            if(direction != null) {\r
+                criteria.add(Restrictions.eq(direction.name(), taxon));\r
+            }\r
+\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<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();\r
-                   defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                   \r
-                   return result;\r
-               } else {\r
-                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\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
-                       List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();\r
-                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                       \r
-                       // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
-                       // and we can't live without this functionality in CATE as it screws up the whole \r
-                       // taxon tree thing\r
-                       if(orderHints != null && !orderHints.isEmpty()) {\r
-                           SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());\r
-                           sortedList.addAll(result);\r
-                           return new ArrayList<TaxonRelationship>(sortedList);\r
-                       }\r
-                       \r
-                       return result;\r
-               }\r
-       }\r
-       \r
-       class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {\r
-\r
-               public int compare(TaxonRelationship o1, TaxonRelationship o2) {\r
-                       return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());\r
-               }\r
-               \r
-       }\r
-       \r
-       class SynonymRelationshipFromTaxonComparator implements Comparator<SynonymRelationship> {\r
-\r
-               public int compare(SynonymRelationship o1, SynonymRelationship o2) {\r
-                       return o1.getSynonym().getTitleCache().compareTo(o2.getSynonym().getTitleCache());\r
-               }\r
-               \r
-       }\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
-        */\r
-       public List<SynonymRelationship> getSynonyms(Taxon taxon, SynonymRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {\r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\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<TaxonRelationship> result = (List<TaxonRelationship>)criteria.list();\r
+            defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+\r
+            return result;\r
+        } else {\r
+            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
+            query.add(AuditEntity.relatedId("relatedTo").eq(taxon.getId()));\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\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
+            List<TaxonRelationship> result = (List<TaxonRelationship>)query.getResultList();\r
+            defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+\r
+            // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
+            // and we can't live without this functionality in CATE as it screws up the whole\r
+            // taxon tree thing\r
+            if(orderHints != null && !orderHints.isEmpty()) {\r
+                SortedSet<TaxonRelationship> sortedList = new TreeSet<TaxonRelationship>(new TaxonRelationshipFromTaxonComparator());\r
+                sortedList.addAll(result);\r
+                return new ArrayList<TaxonRelationship>(sortedList);\r
+            }\r
+\r
+            return result;\r
+        }\r
+    }\r
+\r
+    class TaxonRelationshipFromTaxonComparator implements Comparator<TaxonRelationship> {\r
+\r
+        public int compare(TaxonRelationship o1, TaxonRelationship o2) {\r
+            return o1.getFromTaxon().getTitleCache().compareTo(o2.getFromTaxon().getTitleCache());\r
+        }\r
+\r
+    }\r
+\r
+    class SynonymRelationshipFromTaxonComparator implements Comparator<SynonymRelationship> {\r
+\r
+        public int compare(SynonymRelationship o1, SynonymRelationship o2) {\r
+            return o1.getSynonym().getTitleCache().compareTo(o2.getSynonym().getTitleCache());\r
+        }\r
+\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Taxon, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\r
+     */\r
+    public List<SynonymRelationship> getSynonyms(Taxon taxon, 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("relatedTo", taxon));\r
-                   if(type != null) {\r
-                       criteria.add(Restrictions.eq("type", type));\r
-                   } \r
-               \r
+\r
+            criteria.add(Restrictions.eq("relatedTo", taxon));\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("relatedTo").eq(taxon.getId()));\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\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
-                       List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
-                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                       \r
-                       return result;\r
-               }\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\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
+\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("relatedTo").eq(taxon.getId()));\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\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
+            List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
+            defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+\r
+            return result;\r
+        }\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getSynonyms(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.SynonymRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)\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
+\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
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\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
-                       List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
-                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                       \r
-                       return result;\r
-               }\r
-       }\r
-       \r
-       @Override\r
-       public void rebuildIndex() {\r
-               FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
-               \r
-               for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base\r
-                       Hibernate.initialize(taxonBase.getName());\r
-                       fullTextSession.index(taxonBase);\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
-               if (alternativeSpellingSuggestionParser != null) {\r
-                       try {\r
-\r
-                               alternativeSpellingSuggestionParser.parse(queryString);\r
-                               org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);\r
-                               if (alternativeQuery != null) {\r
-                                       alternativeQueryString = alternativeQuery\r
-                                                       .toString("name.titleCache");\r
-                               }\r
-\r
-                       } catch (ParseException e) {\r
-                               throw new QueryParseException(e, queryString);\r
-                       }\r
-               }\r
-               return alternativeQueryString;\r
-       }\r
-       \r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)\r
-        */\r
-       public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification) {\r
-\r
-               int classificationId = classification.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.classification_id = " + classificationId;\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
-                       Classification classification, MatchMode matchMode,\r
-                       Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber) {\r
-               // TODO Auto-generated method stub\r
-               return null;\r
-       }\r
-       \r
-       \r
-       public List<Synonym>  createAllInferredSynonyms(Taxon taxon, Classification tree){\r
-               List <Synonym> inferredSynonyms = new ArrayList<Synonym>();\r
-               \r
-               inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_EPITHET_OF()));\r
-               inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_GENUS_OF()));\r
-               inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.POTENTIAL_COMBINATION_OF()));\r
-               \r
-               return inferredSynonyms;\r
-       }\r
-       \r
-\r
-       /**\r
-        * Returns an existing ZoologicalName or extends an internal hashmap if it does not exist.\r
-        * Very likely only useful for createInferredSynonyms().\r
-        * @param uuid\r
-        * @param zooHashMap\r
-        * @return\r
-        */\r
-       private ZoologicalName getZoologicalName(UUID uuid, HashMap <UUID, ZoologicalName> zooHashMap) {\r
-               ZoologicalName taxonName = this.taxonNameDao.findZoologicalNameByUUID(uuid);\r
-               if (taxonName == null) {\r
-                       taxonName = zooHashMap.get(uuid);\r
-               }\r
-               return taxonName;\r
-       }\r
-\r
-       public List<Synonym> createInferredSynonyms(Taxon taxon, Classification tree, SynonymRelationshipType type){\r
-               List <Synonym> inferredSynonyms = new ArrayList<Synonym>();\r
-               List<Synonym> inferredSynonymsToBeRemoved = new ArrayList<Synonym>();\r
-\r
-               HashMap <UUID, ZoologicalName> zooHashMap = new HashMap<UUID, ZoologicalName>();\r
-               UUID uuid;\r
-               \r
-               uuid= taxon.getName().getUuid();\r
-               ZoologicalName taxonName = getZoologicalName(uuid, zooHashMap);\r
-               String epithetOfTaxon = taxonName.getSpecificEpithet();\r
-               String genusOfTaxon = taxonName.getGenusOrUninomial();\r
-               Set<TaxonNode> nodes = taxon.getTaxonNodes();\r
-               List<String> taxonNames = new ArrayList<String>();\r
-               \r
-               for (TaxonNode node: nodes){\r
-                       HashMap<String, String> synonymsGenus = new HashMap<String, String>(); // Changed this to be able to store the idInSource to a genusName\r
-                       List<String> synonymsEpithet = new ArrayList<String>();\r
-                       \r
-                       if (node.getClassification().equals(tree)){\r
-                               if (!node.isTopmostNode()){\r
-                               TaxonNode parent = (TaxonNode)node.getParent();\r
-                               parent = (TaxonNode)HibernateProxyHelper.deproxy(parent);\r
-                               TaxonNameBase parentName = parent.getTaxon().getName();\r
-                               parentName = (TaxonNameBase)HibernateProxyHelper.deproxy(parentName);\r
-                               \r
-                               //create inferred synonyms for species, subspecies or subgenus\r
-                               if (parentName.isGenus() || parentName.isSpecies() || parentName.getRank().equals(Rank.SUBGENUS())){\r
-                                       \r
-                                       Synonym inferredEpithet;\r
-                                       Synonym inferredGenus = null;\r
-                                       Synonym potentialCombination;\r
-                                       \r
-                                       List<String> propertyPaths = new ArrayList<String>();\r
-                                       propertyPaths.add("synonym");\r
-                                       propertyPaths.add("synonym.name");\r
-                                       List<OrderHint> orderHints = new ArrayList<OrderHint>();\r
-                                       orderHints.add(new OrderHint("relatedFrom.titleCache", SortOrder.ASCENDING));\r
-                               \r
-                                       List<SynonymRelationship> synonymRelationshipsOfGenus = getSynonyms(parent.getTaxon(), SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);\r
-                                       List<SynonymRelationship> synonymRelationshipsOfTaxon= getSynonyms(taxon, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);                                                                       \r
-                                       \r
-                                       if (type.equals(SynonymRelationshipType.INFERRED_EPITHET_OF())){\r
-                                                                                               \r
-                                               for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){\r
-                                                       TaxonNameBase synName;\r
-                                                       ZoologicalName inferredSynName;\r
-                                                       Synonym syn = synonymRelationOfGenus.getSynonym();\r
-                                                       HibernateProxyHelper.deproxy(syn);\r
-                                                       \r
-                                                       // Determine the idInSource\r
-                                                       String idInSource = getIdInSource(syn);\r
-                                                       \r
-                                                       // Determine the sourceReference\r
-                                                       Reference sourceReference = syn.getSec();\r
-                                                       \r
-                                                       synName = syn.getName();\r
-                                                       ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
-                                                       String synGenusName = zooName.getGenusOrUninomial();\r
-                                                       if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){\r
-                                                               synonymsGenus.put(synGenusName, idInSource);\r
-                                                       }\r
-                                                       inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
-                                                       \r
-                                                       // DEBUG\r
-                                                       if (epithetOfTaxon == null) {\r
-                                                               logger.error("This specificEpithet is NULL");\r
-                                                       }\r
-                                                       \r
-                                                       inferredSynName.setSpecificEpithet(epithetOfTaxon);\r
-                                                       inferredSynName.setGenusOrUninomial(synGenusName);\r
-                                                       inferredEpithet = Synonym.NewInstance(inferredSynName, null);\r
-                                                       \r
-                                                       // Set the sourceReference\r
-                                                       inferredEpithet.setSec(sourceReference);\r
-\r
-                                                       // Add the original source\r
-                                                       if (idInSource != null) {\r
-                                                               IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredEpithetOf", syn.getSec(), null);\r
-                                                               \r
-                                                               // Add the citation\r
-                                                               Reference citation = getCitation(syn);\r
-                                                               if (citation != null) {\r
-                                                                       originalSource.setCitation(citation);\r
-                                                                       inferredEpithet.addSource(originalSource);\r
-                                                               }\r
-                                                       }\r
-                                                       \r
-                                                       taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());\r
-                                                       inferredSynonyms.add(inferredEpithet);\r
-                                                       inferredSynName.generateTitle();\r
-                                                       zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
-                                                       taxonNames.add(inferredSynName.getNameCache());\r
-                                               }\r
-                                               \r
-                                               if (!taxonNames.isEmpty()){\r
-                                               List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
-                                               ZoologicalName name;\r
-                                               if (!synNotInCDM.isEmpty()){\r
-                                                       inferredSynonymsToBeRemoved.clear();\r
-                                                       \r
-                                                       for (Synonym syn :inferredSynonyms){\r
-                                                               name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
-                                                               if (!synNotInCDM.contains(name.getNameCache())){\r
-                                                                       inferredSynonymsToBeRemoved.add(syn);\r
-                                                               }\r
-                                                       }\r
-                                                       \r
-                                                       // Remove identified Synonyms from inferredSynonyms\r
-                                                       for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
-                                                               inferredSynonyms.remove(synonym);\r
-                                                       }\r
-                                               }\r
-                                               }\r
-                                               \r
-                                       }else if (type.equals(SynonymRelationshipType.INFERRED_GENUS_OF())){\r
-                                               \r
-                                               \r
-                                               for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){\r
-                                                       TaxonNameBase synName;\r
-                                                       ZoologicalName inferredSynName;\r
-                                                       \r
-                                                       Synonym syn = synonymRelationOfTaxon.getSynonym();\r
-                                                       synName =syn.getName();\r
-                                                       HibernateProxyHelper.deproxy(syn);\r
-                                                       \r
-                                                       // Determine the idInSource\r
-                                                       String idInSource = getIdInSource(syn);\r
-                                                       \r
-                                                       // Determine the sourceReference\r
-                                                       Reference sourceReference = syn.getSec();\r
-\r
-                                                       synName = syn.getName();\r
-                                                       ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
-                                                       String speciesEpithetName = zooName.getSpecificEpithet();\r
-                                                       if (synonymsEpithet != null && !synonymsEpithet.contains(speciesEpithetName)){\r
-                                                               synonymsEpithet.add(speciesEpithetName);\r
-                                                       }\r
-                                                       inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
-                                                       inferredSynName.setSpecificEpithet(speciesEpithetName);\r
-                                                       inferredSynName.setGenusOrUninomial(genusOfTaxon);\r
-                                                       inferredGenus = Synonym.NewInstance(inferredSynName, null);\r
-                                                       \r
-                                                       // Set the sourceReference\r
-                                                       inferredGenus.setSec(sourceReference);\r
-                                                       \r
-                                                       // Add the original source\r
-                                                       if (idInSource != null) {\r
-                                                               IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredGenusOf", syn.getSec(), null);\r
-                                                               \r
-                                                               // Add the citation\r
-                                                               Reference citation = getCitation(syn);\r
-                                                               if (citation != null) {\r
-                                                                       originalSource.setCitation(citation);\r
-                                                                       inferredGenus.addSource(originalSource);\r
-                                                               }\r
-                                                       }\r
-\r
-                                                       taxon.addSynonym(inferredGenus, SynonymRelationshipType.INFERRED_EPITHET_OF());\r
-                                                       inferredSynonyms.add(inferredGenus);\r
-                                                       inferredSynName.generateTitle();\r
-                                                       zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
-                                                       taxonNames.add(inferredSynName.getNameCache());\r
-                                               }\r
-                                               \r
-                                               if (!taxonNames.isEmpty()){\r
-                                                       List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
-                                                       ZoologicalName name;\r
-                                                       if (!synNotInCDM.isEmpty()){\r
-                                                               inferredSynonymsToBeRemoved.clear();\r
-                                                               \r
-                                                               for (Synonym syn :inferredSynonyms){\r
-                                                                       name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
-                                                                       if (!synNotInCDM.contains(name.getNameCache())){\r
-                                                                               inferredSynonymsToBeRemoved.add(syn);\r
-                                                                       }\r
-                                                               }\r
-                                                               \r
-                                                               // Remove identified Synonyms from inferredSynonyms\r
-                                                               for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
-                                                                       inferredSynonyms.remove(synonym);\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-                                               \r
-                                       }else if (type.equals(SynonymRelationshipType.POTENTIAL_COMBINATION_OF())){\r
-                                               \r
-                                               Reference sourceReference = null; // TODO: Determination of sourceReference is redundant\r
-                                               \r
-                                               for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){\r
-                                                       TaxonNameBase synName;\r
-                                                       Synonym syn = synonymRelationOfGenus.getSynonym();\r
-                                                       synName =syn.getName();\r
-                                                       \r
-                                                       HibernateProxyHelper.deproxy(syn);\r
-                                                       \r
-                                                       // Set the sourceReference\r
-                                                       sourceReference = syn.getSec();\r
-\r
-                                                       // Determine the idInSource\r
-                                                       String idInSource = getIdInSource(syn);\r
-\r
-                                                       ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
-                                                       String synGenusName = zooName.getGenusOrUninomial();\r
-                                                       if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){\r
-                                                               synonymsGenus.put(synGenusName, idInSource);\r
-                                                       }\r
-                                               }\r
-                                               \r
-                                               ZoologicalName inferredSynName;\r
-                                               for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){\r
-                                                       \r
-                                                       Synonym syn = synonymRelationOfTaxon.getSynonym();\r
-                                                       HibernateProxyHelper.deproxy(syn);\r
-                                                       \r
-                                                       // Set sourceReference\r
-                                                       sourceReference = syn.getSec();\r
-                                                       \r
-                                                       ZoologicalName zooName = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
-                                                       String epithetName = zooName.getSpecificEpithet();\r
-                                                       if (epithetName != null && !synonymsEpithet.contains(epithetName)){\r
-                                                               synonymsEpithet.add(epithetName);\r
-                                                       }\r
-                                               }\r
-                                               for (String epithetName:synonymsEpithet){\r
-                                                       for (String genusName: synonymsGenus.keySet()){\r
-                                                               inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
-                                                               inferredSynName.setSpecificEpithet(epithetName);\r
-                                                               inferredSynName.setGenusOrUninomial(genusName);\r
-                                                               potentialCombination = Synonym.NewInstance(inferredSynName, null);\r
-                                                               \r
-                                                               // Set the sourceReference\r
-                                                               potentialCombination.setSec(sourceReference);\r
-                                                               \r
-                                                               // Add the original source\r
-                                                               String idInSource = synonymsGenus.get(genusName);\r
-                                                               if (idInSource != null) {\r
-                                                                       IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "PotentialCombinationOf", sourceReference, null);\r
-                                                                       \r
-                                                                       // Add the citation\r
-                                                                       if (sourceReference != null) {\r
-                                                                               originalSource.setCitation(sourceReference);\r
-                                                                               potentialCombination.addSource(originalSource);\r
-                                                                       }\r
-                                                               }\r
-\r
-                                                               inferredSynonyms.add(potentialCombination);\r
-                                                               inferredSynName.generateTitle();\r
-                                                               zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
-                                                               taxonNames.add(inferredSynName.getNameCache());\r
-                                                       }\r
-                                                       \r
-                                                       if (!taxonNames.isEmpty()){\r
-                                                               List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
-                                                               ZoologicalName name;\r
-                                                               if (!synNotInCDM.isEmpty()){\r
-                                                                       inferredSynonymsToBeRemoved.clear();\r
-                                                                       \r
-                                                                       for (Synonym syn :inferredSynonyms){\r
-                                                                               try{\r
-                                                                                       name = (ZoologicalName) syn.getName();\r
-                                                                               }catch (ClassCastException e){\r
-                                                                                       name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
-                                                                               }\r
-                                                                               if (!synNotInCDM.contains(name.getNameCache())){\r
-                                                                                       inferredSynonymsToBeRemoved.add(syn);\r
-                                                                               }\r
-                                                                       }\r
-                                                                       \r
-                                                                       // Remove identified Synonyms from inferredSynonyms\r
-                                                                       for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
-                                                                               inferredSynonyms.remove(synonym);\r
-                                                                       }\r
-                                                               }\r
-                                                       }\r
-                                               }\r
-                                       }else {\r
-                                               logger.info("The synonymrelationship type is not defined.");\r
-                                               return null;\r
-                                       }\r
-                               }\r
-                       }\r
-                       }\r
-                       }\r
-                       \r
-               \r
-               return inferredSynonyms;\r
-       }\r
-\r
-\r
-       /**\r
-        * Returns the idInSource for a given Synonym.\r
-        * @param syn\r
-        */\r
-       private String getIdInSource(Synonym syn) {\r
-               String idInSource = null;\r
-               Set<IdentifiableSource> sources = syn.getSources();\r
-               if (sources.size() == 1) {\r
-                       IdentifiableSource source = sources.iterator().next();\r
-                       if (source != null) {\r
-                               idInSource  = source.getIdInSource();\r
-                       }\r
-               } else if (sources.size() > 1) {\r
-                       int count = 1;\r
-                       idInSource = "";\r
-                       for (IdentifiableSource source : sources) {\r
-                               idInSource += source.getIdInSource();\r
-                               if (count < sources.size()) {\r
-                                       idInSource += "; ";\r
-                               }\r
-                               count++;\r
-                       }\r
-               }\r
-               \r
-               return idInSource;\r
-       }\r
-       \r
-       /**\r
-        * Returns the citation for a given Synonym.\r
-        * @param syn\r
-        */\r
-       private Reference getCitation(Synonym syn) {\r
-               Reference citation = null;\r
-               Set<IdentifiableSource> sources = syn.getSources();\r
-               if (sources.size() == 1) {\r
-                       IdentifiableSource source = sources.iterator().next();\r
-                       if (source != null) {\r
-                               citation = source.getCitation();\r
-                       }\r
-               } else if (sources.size() > 1) {\r
-                       logger.warn("This Synonym has more than one source: " + syn.getUuid() + " (" + syn.getTitleCache() +")");\r
-               }\r
-               \r
-               return citation;\r
-       }\r
-       \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
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\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
+            List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
+            defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+\r
+            return result;\r
+        }\r
+    }\r
+\r
+    @Override\r
+    public void rebuildIndex() {\r
+        FullTextSession fullTextSession = Search.getFullTextSession(getSession());\r
+\r
+        for(TaxonBase taxonBase : list(null,null)) { // re-index all taxon base\r
+            Hibernate.initialize(taxonBase.getName());\r
+            fullTextSession.index(taxonBase);\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
+        if (alternativeSpellingSuggestionParser != null) {\r
+            try {\r
+\r
+                alternativeSpellingSuggestionParser.parse(queryString);\r
+                org.apache.lucene.search.Query alternativeQuery = alternativeSpellingSuggestionParser.suggest(queryString);\r
+                if (alternativeQuery != null) {\r
+                    alternativeQueryString = alternativeQuery\r
+                            .toString("name.titleCache");\r
+                }\r
+\r
+            } catch (ParseException e) {\r
+                throw new QueryParseException(e, queryString);\r
+            }\r
+        }\r
+        return alternativeQueryString;\r
+    }\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.api.service.ITaxonService#getUuidAndTitleCacheOfAcceptedTaxa(eu.etaxonomy.cdm.model.taxon.Classification)\r
+     */\r
+    public List<UuidAndTitleCache<TaxonNode>> getTaxonNodeUuidAndTitleCacheOfAcceptedTaxaByClassification(Classification classification) {\r
+\r
+        int classificationId = classification.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.classification_id = " + classificationId;\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
+            Classification classification, MatchMode matchMode,\r
+            Set<NamedArea> namedAreas, Integer pageSize, Integer pageNumber) {\r
+        // TODO Auto-generated method stub\r
+        return null;\r
+    }\r
+\r
+\r
+    public List<Synonym>  createAllInferredSynonyms(Taxon taxon, Classification tree){\r
+        List <Synonym> inferredSynonyms = new ArrayList<Synonym>();\r
+\r
+        inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_EPITHET_OF()));\r
+        inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.INFERRED_GENUS_OF()));\r
+        inferredSynonyms.addAll(createInferredSynonyms(taxon, tree, SynonymRelationshipType.POTENTIAL_COMBINATION_OF()));\r
+\r
+        return inferredSynonyms;\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns an existing ZoologicalName or extends an internal hashmap if it does not exist.\r
+     * Very likely only useful for createInferredSynonyms().\r
+     * @param uuid\r
+     * @param zooHashMap\r
+     * @return\r
+     */\r
+    private ZoologicalName getZoologicalName(UUID uuid, HashMap <UUID, ZoologicalName> zooHashMap) {\r
+        ZoologicalName taxonName = this.taxonNameDao.findZoologicalNameByUUID(uuid);\r
+        if (taxonName == null) {\r
+            taxonName = zooHashMap.get(uuid);\r
+        }\r
+        return taxonName;\r
+    }\r
+\r
+    public List<Synonym> createInferredSynonyms(Taxon taxon, Classification tree, SynonymRelationshipType type){\r
+        List <Synonym> inferredSynonyms = new ArrayList<Synonym>();\r
+        List<Synonym> inferredSynonymsToBeRemoved = new ArrayList<Synonym>();\r
+\r
+        HashMap <UUID, ZoologicalName> zooHashMap = new HashMap<UUID, ZoologicalName>();\r
+        UUID uuid;\r
+\r
+        uuid= taxon.getName().getUuid();\r
+        ZoologicalName taxonName = getZoologicalName(uuid, zooHashMap);\r
+        String epithetOfTaxon = taxonName.getSpecificEpithet();\r
+        String genusOfTaxon = taxonName.getGenusOrUninomial();\r
+        Set<TaxonNode> nodes = taxon.getTaxonNodes();\r
+         List<String> taxonNames = new ArrayList<String>();\r
+\r
+        for (TaxonNode node: nodes){\r
+            HashMap<String, String> synonymsGenus = new HashMap<String, String>(); // Changed this to be able to store the idInSource to a genusName\r
+            List<String> synonymsEpithet = new ArrayList<String>();\r
+\r
+            if (node.getClassification().equals(tree)){\r
+                if (!node.isTopmostNode()){\r
+                TaxonNode parent = (TaxonNode)node.getParent();\r
+                parent = (TaxonNode)HibernateProxyHelper.deproxy(parent);\r
+                TaxonNameBase parentName = parent.getTaxon().getName();\r
+                parentName = (TaxonNameBase)HibernateProxyHelper.deproxy(parentName);\r
+\r
+                //create inferred synonyms for species, subspecies or subgenus\r
+                if (parentName.isGenus() || parentName.isSpecies() || parentName.getRank().equals(Rank.SUBGENUS())){\r
+\r
+                    Synonym inferredEpithet;\r
+                    Synonym inferredGenus = null;\r
+                    Synonym potentialCombination;\r
+\r
+                    List<String> propertyPaths = new ArrayList<String>();\r
+                    propertyPaths.add("synonym");\r
+                    propertyPaths.add("synonym.name");\r
+                    List<OrderHint> orderHints = new ArrayList<OrderHint>();\r
+                    orderHints.add(new OrderHint("relatedFrom.titleCache", SortOrder.ASCENDING));\r
+\r
+                    List<SynonymRelationship> synonymRelationshipsOfGenus = getSynonyms(parent.getTaxon(), SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);\r
+                    List<SynonymRelationship> synonymRelationshipsOfTaxon= getSynonyms(taxon, SynonymRelationshipType.HETEROTYPIC_SYNONYM_OF(), null, null,orderHints,propertyPaths);\r
+\r
+                    if (type.equals(SynonymRelationshipType.INFERRED_EPITHET_OF())){\r
+\r
+                        for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){\r
+                            TaxonNameBase synName;\r
+                            ZoologicalName inferredSynName;\r
+                            Synonym syn = synonymRelationOfGenus.getSynonym();\r
+                            HibernateProxyHelper.deproxy(syn);\r
+\r
+                            // Determine the idInSource\r
+                            String idInSource = getIdInSource(syn);\r
+\r
+                            // Determine the sourceReference\r
+                            Reference sourceReference = syn.getSec();\r
+\r
+                            synName = syn.getName();\r
+                            ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
+                            String synGenusName = zooName.getGenusOrUninomial();\r
+                            if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){\r
+                                synonymsGenus.put(synGenusName, idInSource);\r
+                            }\r
+                            inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
+\r
+                            // DEBUG\r
+                            if (epithetOfTaxon == null) {\r
+                                logger.error("This specificEpithet is NULL");\r
+                            }\r
+\r
+                            inferredSynName.setSpecificEpithet(epithetOfTaxon);\r
+                            inferredSynName.setGenusOrUninomial(synGenusName);\r
+                            inferredEpithet = Synonym.NewInstance(inferredSynName, null);\r
+\r
+                            // Set the sourceReference\r
+                            inferredEpithet.setSec(sourceReference);\r
+\r
+                            // Add the original source\r
+                            if (idInSource != null) {\r
+                                IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredEpithetOf", syn.getSec(), null);\r
+\r
+                                // Add the citation\r
+                                Reference citation = getCitation(syn);\r
+                                if (citation != null) {\r
+                                    originalSource.setCitation(citation);\r
+                                    inferredEpithet.addSource(originalSource);\r
+                                }\r
+                            }\r
+\r
+                            taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());\r
+                            inferredSynonyms.add(inferredEpithet);\r
+                            inferredSynName.generateTitle();\r
+                            zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
+                            taxonNames.add(inferredSynName.getNameCache());\r
+                        }\r
+\r
+                        if (!taxonNames.isEmpty()){\r
+                        List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
+                        ZoologicalName name;\r
+                        if (!synNotInCDM.isEmpty()){\r
+                            inferredSynonymsToBeRemoved.clear();\r
+\r
+                            for (Synonym syn :inferredSynonyms){\r
+                                name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
+                                if (!synNotInCDM.contains(name.getNameCache())){\r
+                                    inferredSynonymsToBeRemoved.add(syn);\r
+                                }\r
+                            }\r
+\r
+                            // Remove identified Synonyms from inferredSynonyms\r
+                            for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
+                                inferredSynonyms.remove(synonym);\r
+                            }\r
+                        }\r
+                        }\r
+\r
+                    }else if (type.equals(SynonymRelationshipType.INFERRED_GENUS_OF())){\r
+\r
+\r
+                        for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){\r
+                            TaxonNameBase synName;\r
+                            ZoologicalName inferredSynName;\r
+\r
+                            Synonym syn = synonymRelationOfTaxon.getSynonym();\r
+                            synName =syn.getName();\r
+                            HibernateProxyHelper.deproxy(syn);\r
+\r
+                            // Determine the idInSource\r
+                            String idInSource = getIdInSource(syn);\r
+\r
+                            // Determine the sourceReference\r
+                            Reference sourceReference = syn.getSec();\r
+\r
+                            synName = syn.getName();\r
+                            ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
+                            String speciesEpithetName = zooName.getSpecificEpithet();\r
+                            if (synonymsEpithet != null && !synonymsEpithet.contains(speciesEpithetName)){\r
+                                synonymsEpithet.add(speciesEpithetName);\r
+                            }\r
+                            inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
+                            inferredSynName.setSpecificEpithet(speciesEpithetName);\r
+                            inferredSynName.setGenusOrUninomial(genusOfTaxon);\r
+                            inferredGenus = Synonym.NewInstance(inferredSynName, null);\r
+\r
+                            // Set the sourceReference\r
+                            inferredGenus.setSec(sourceReference);\r
+\r
+                            // Add the original source\r
+                            if (idInSource != null) {\r
+                                IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "InferredGenusOf", syn.getSec(), null);\r
+\r
+                                // Add the citation\r
+                                Reference citation = getCitation(syn);\r
+                                if (citation != null) {\r
+                                    originalSource.setCitation(citation);\r
+                                    inferredGenus.addSource(originalSource);\r
+                                }\r
+                            }\r
+\r
+                            taxon.addSynonym(inferredGenus, SynonymRelationshipType.INFERRED_EPITHET_OF());\r
+                            inferredSynonyms.add(inferredGenus);\r
+                            inferredSynName.generateTitle();\r
+                            zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
+                            taxonNames.add(inferredSynName.getNameCache());\r
+                        }\r
+\r
+                        if (!taxonNames.isEmpty()){\r
+                            List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
+                            ZoologicalName name;\r
+                            if (!synNotInCDM.isEmpty()){\r
+                                inferredSynonymsToBeRemoved.clear();\r
+\r
+                                for (Synonym syn :inferredSynonyms){\r
+                                    name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
+                                    if (!synNotInCDM.contains(name.getNameCache())){\r
+                                        inferredSynonymsToBeRemoved.add(syn);\r
+                                    }\r
+                                }\r
+\r
+                                // Remove identified Synonyms from inferredSynonyms\r
+                                for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
+                                    inferredSynonyms.remove(synonym);\r
+                                }\r
+                            }\r
+                        }\r
+\r
+                    }else if (type.equals(SynonymRelationshipType.POTENTIAL_COMBINATION_OF())){\r
+\r
+                        Reference sourceReference = null; // TODO: Determination of sourceReference is redundant\r
+\r
+                        for (SynonymRelationship synonymRelationOfGenus:synonymRelationshipsOfGenus){\r
+                            TaxonNameBase synName;\r
+                            Synonym syn = synonymRelationOfGenus.getSynonym();\r
+                            synName =syn.getName();\r
+\r
+                            HibernateProxyHelper.deproxy(syn);\r
+\r
+                            // Set the sourceReference\r
+                            sourceReference = syn.getSec();\r
+\r
+                            // Determine the idInSource\r
+                            String idInSource = getIdInSource(syn);\r
+\r
+                            ZoologicalName zooName = getZoologicalName(synName.getUuid(), zooHashMap);\r
+                            String synGenusName = zooName.getGenusOrUninomial();\r
+                            if (synGenusName != null && !synonymsGenus.containsKey(synGenusName)){\r
+                                synonymsGenus.put(synGenusName, idInSource);\r
+                            }\r
+                        }\r
+\r
+                        ZoologicalName inferredSynName;\r
+                        for (SynonymRelationship synonymRelationOfTaxon:synonymRelationshipsOfTaxon){\r
+\r
+                            Synonym syn = synonymRelationOfTaxon.getSynonym();\r
+                            HibernateProxyHelper.deproxy(syn);\r
+\r
+                            // Set sourceReference\r
+                            sourceReference = syn.getSec();\r
+\r
+                            ZoologicalName zooName = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
+                            String epithetName = zooName.getSpecificEpithet();\r
+                            if (epithetName != null && !synonymsEpithet.contains(epithetName)){\r
+                                synonymsEpithet.add(epithetName);\r
+                            }\r
+                        }\r
+                        for (String epithetName:synonymsEpithet){\r
+                            for (String genusName: synonymsGenus.keySet()){\r
+                                inferredSynName = ZoologicalName.NewInstance(Rank.SPECIES());\r
+                                inferredSynName.setSpecificEpithet(epithetName);\r
+                                inferredSynName.setGenusOrUninomial(genusName);\r
+                                potentialCombination = Synonym.NewInstance(inferredSynName, null);\r
+\r
+                                // Set the sourceReference\r
+                                potentialCombination.setSec(sourceReference);\r
+\r
+                                // Add the original source\r
+                                String idInSource = synonymsGenus.get(genusName);\r
+                                if (idInSource != null) {\r
+                                    IdentifiableSource originalSource = IdentifiableSource.NewInstance(idInSource, "PotentialCombinationOf", sourceReference, null);\r
+\r
+                                    // Add the citation\r
+                                    if (sourceReference != null) {\r
+                                        originalSource.setCitation(sourceReference);\r
+                                        potentialCombination.addSource(originalSource);\r
+                                    }\r
+                                }\r
+\r
+                                inferredSynonyms.add(potentialCombination);\r
+                                inferredSynName.generateTitle();\r
+                                zooHashMap.put(inferredSynName.getUuid(), inferredSynName);\r
+                                taxonNames.add(inferredSynName.getNameCache());\r
+                            }\r
+\r
+                            if (!taxonNames.isEmpty()){\r
+                                List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
+                                ZoologicalName name;\r
+                                if (!synNotInCDM.isEmpty()){\r
+                                    inferredSynonymsToBeRemoved.clear();\r
+\r
+                                    for (Synonym syn :inferredSynonyms){\r
+                                        try{\r
+                                            name = (ZoologicalName) syn.getName();\r
+                                        }catch (ClassCastException e){\r
+                                            name = getZoologicalName(syn.getName().getUuid(), zooHashMap);\r
+                                        }\r
+                                        if (!synNotInCDM.contains(name.getNameCache())){\r
+                                            inferredSynonymsToBeRemoved.add(syn);\r
+                                        }\r
+                                    }\r
+\r
+                                    // Remove identified Synonyms from inferredSynonyms\r
+                                    for (Synonym synonym : inferredSynonymsToBeRemoved) {\r
+                                        inferredSynonyms.remove(synonym);\r
+                                    }\r
+                                }\r
+                            }\r
+                        }\r
+                    }else {\r
+                        logger.info("The synonymrelationship type is not defined.");\r
+                        return null;\r
+                    }\r
+                }\r
+            }\r
+            }\r
+            }\r
+\r
+\r
+        return inferredSynonyms;\r
+    }\r
+\r
+\r
+    /**\r
+     * Returns the idInSource for a given Synonym.\r
+     * @param syn\r
+     */\r
+    private String getIdInSource(Synonym syn) {\r
+        String idInSource = null;\r
+        Set<IdentifiableSource> sources = syn.getSources();\r
+        if (sources.size() == 1) {\r
+            IdentifiableSource source = sources.iterator().next();\r
+            if (source != null) {\r
+                idInSource  = source.getIdInSource();\r
+            }\r
+        } else if (sources.size() > 1) {\r
+            int count = 1;\r
+            idInSource = "";\r
+            for (IdentifiableSource source : sources) {\r
+                idInSource += source.getIdInSource();\r
+                if (count < sources.size()) {\r
+                    idInSource += "; ";\r
+                }\r
+                count++;\r
+            }\r
+        }\r
+\r
+        return idInSource;\r
+    }\r
+\r
+    /**\r
+     * Returns the citation for a given Synonym.\r
+     * @param syn\r
+     */\r
+    private Reference getCitation(Synonym syn) {\r
+        Reference citation = null;\r
+        Set<IdentifiableSource> sources = syn.getSources();\r
+        if (sources.size() == 1) {\r
+            IdentifiableSource source = sources.iterator().next();\r
+            if (source != null) {\r
+                citation = source.getCitation();\r
+            }\r
+        } else if (sources.size() > 1) {\r
+            logger.warn("This Synonym has more than one source: " + syn.getUuid() + " (" + syn.getTitleCache() +")");\r
+        }\r
+\r
+        return citation;\r
+    }\r
+\r
 /*     private void xxx(List<SynonymRelationship> synonymRelationships, HashMap <UUID, ZoologicalName> zooHashMap, SynonymRelationshipType type, String addString){\r
-               \r
-               for (SynonymRelationship synonymRelation:synonymRelationships){\r
-                       TaxonNameBase synName;\r
-                       NonViralName inferredSynName;\r
-                       Synonym syn = synonymRelation.getSynonym();\r
-                       HibernateProxyHelper.deproxy(syn);\r
-                       \r
-                       synName = syn.getName();\r
-                       ZoologicalName zooName = zooHashMap.get(synName.getUuid());\r
-                       String synGenusName = zooName.getGenusOrUninomial();\r
-                       \r
-                       switch(type.getId()){\r
-                       case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():\r
-                               inferredSynName.setSpecificEpithet(addString);\r
-                               break;\r
-                       case SynonymRelationshipType.INFERRED_GENUS_OF().getId():\r
-                               break;\r
-                       case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():\r
-                               break;\r
-                       default:\r
-                       }\r
-                       if (!synonymsGenus.contains(synGenusName)){\r
-                               synonymsGenus.add(synGenusName);\r
-                       }\r
-                       inferredSynName = NonViralName.NewInstance(Rank.SPECIES());\r
-                       inferredSynName.setSpecificEpithet(epithetOfTaxon);\r
-                       inferredSynName.setGenusOrUninomial(synGenusName);\r
-                       inferredEpithet = Synonym.NewInstance(inferredSynName, null);\r
-                       taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());\r
-                       inferredSynonyms.add(inferredEpithet);\r
-                       inferredSynName.generateTitle();\r
-                       taxonNames.add(inferredSynName.getNameCache());\r
-               }\r
-                       \r
-               \r
-               if (!taxonNames.isEmpty()){\r
-               List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
-               ZoologicalName name;\r
-               if (!synNotInCDM.isEmpty()){\r
-                       for (Synonym syn :inferredSynonyms){\r
-                               name =zooHashMap.get(syn.getName().getUuid());\r
-                               if (!synNotInCDM.contains(name.getNameCache())){\r
-                                       inferredSynonyms.remove(syn);\r
-                               }\r
-                       }\r
-               }\r
-               }\r
-       }*/\r
-\r
-       /*\r
-        * (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()\r
-        */\r
-       public int countAllRelationships() {\r
-               List<RelationshipBase> relationships = this.getAllRelationships(null, 0);\r
-               return relationships.size();\r
-       }\r
-       \r
-       \r
-       public List<String> taxaByNameNotInDB(List<String> taxonNames){\r
-               List<TaxonBase> notInDB = new ArrayList<TaxonBase>();\r
-               //get all taxa, already in db\r
-               Query query = getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");\r
-               query.setParameterList("taxonList", taxonNames);\r
-               List<TaxonNameBase> taxaInDB = query.list();\r
-               //compare the original list with the result of the query\r
-               for (TaxonNameBase taxonName: taxaInDB){\r
-                       if (taxonName.isInstanceOf(NonViralName.class)) {\r
-                               NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);\r
-                               String nameCache = nonViralName.getNameCache();\r
-                               if (taxonNames.contains(nameCache)){\r
-                                       taxonNames.remove(nameCache);\r
-                               }\r
-                       }\r
-               }\r
-                               \r
-               return taxonNames;\r
-       }\r
-\r
-       //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?\r
-       public List<UUID> findIdenticalTaxonNameIds(List<String> propertyPaths){\r
-               Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");\r
-               List<UUID> zooNames = query.list();\r
-                                                               \r
-               return zooNames;\r
-               \r
-       }\r
-       \r
-       public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPaths) {\r
-               \r
-               Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");\r
-               \r
-               List<TaxonNameBase> zooNames = query.list();\r
-               \r
-               TaxonNameComparator taxComp = new TaxonNameComparator();\r
-               Collections.sort(zooNames, taxComp);\r
-               \r
-               for (TaxonNameBase taxonNameBase: zooNames){\r
-                       defaultBeanInitializer.initialize(taxonNameBase, propertyPaths);\r
-               }\r
-               \r
-               return zooNames;\r
-       }\r
-       \r
-       public List<TaxonNameBase> findIdenticalNamesNew(List<String> propertyPaths){\r
-               \r
-               //Hole die beiden Source_ids von "Fauna Europaea" und "Erms" und in sources der names darf jeweils nur das entgegengesetzte auftreten (i member of tmb.taxonBases)\r
-               Query query = getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");\r
-               List<String> secRefFauna = query.list();\r
-               query = getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");\r
-               List<String> secRefErms = query.list();\r
-               //Query query = getSession().createQuery("select tmb2.nameCache from ZoologicalName tmb, TaxonBase tb1, ZoologicalName tmb2, TaxonBase tb2 where tmb.id != tmb2.id and tb1.name = tmb and tb2.name = tmb2 and tmb.nameCache = tmb2.nameCache and tb1.sec != tb2.sec");\r
-               //Get all names of fauna europaea\r
-               query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");\r
-               query.setParameter("secRefFauna", secRefFauna.get(0));\r
-               List<String> namesFauna= query.list();\r
-               \r
-               //Get all names of erms\r
-               \r
-               query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");\r
-               query.setParameter("secRefErms", secRefErms.get(0));\r
-               \r
-               List<String> namesErms = query.list();\r
-               /*TaxonNameComparator comp = new TaxonNameComparator();\r
-               Collections.sort(namesFauna);\r
-               Collections.sort(namesErms);\r
-               */\r
-               List <String> identicalNames = new ArrayList<String>();\r
-               String predecessor = "";\r
-               \r
-               for (String nameFauna: namesFauna){\r
-                       if (namesErms.contains(nameFauna)){\r
-                               identicalNames.add(nameFauna);\r
-                       }\r
-               }\r
-               \r
-               \r
-               query = getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");\r
-               query.setParameterList("identicalNames", identicalNames);\r
-               List<TaxonNameBase> result = query.list();\r
-               TaxonNameBase temp = result.get(0);\r
-               \r
-               Iterator<OriginalSourceBase> sources = temp.getSources().iterator();\r
-                               \r
-               TaxonNameComparator taxComp = new TaxonNameComparator();\r
-               Collections.sort(result, taxComp);\r
-               defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-               return result;\r
-               \r
-               }\r
-       \r
-       \r
-       \r
-       public String getPhylumName(TaxonNameBase name){\r
-               List results = new ArrayList();\r
-               try{\r
-               Query query = getSession().createSQLQuery("select getPhylum("+ name.getId()+");");\r
-               results = query.list();\r
-               }catch(Exception e){\r
-                       System.err.println(name.getUuid());\r
-                       return null;\r
-               }\r
-               System.err.println("phylum of "+ name.getTitleCache() );\r
-               return (String)results.get(0);\r
-       }\r
-\r
-\r
-       public long countTaxaByCommonName(String searchString,\r
-                       Classification classification, MatchMode matchMode,\r
-                       Set<NamedArea> namedAreas) {\r
-               boolean doCount = true;\r
-               Query query = prepareTaxaByCommonName(searchString, classification, matchMode, namedAreas, null, null, doCount);\r
-               if (query != null && !query.list().isEmpty()) {\r
-                       Object o = query.uniqueResult();\r
-                       if(o != null) {\r
-                               return (Long)o;\r
-                       }\r
-               }\r
-               return 0;\r
-       }\r
-\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)\r
-        */\r
-       public long deleteSynonymRelationships(Synonym synonym, Taxon taxon) {\r
-               \r
-               String hql = "delete SynonymRelationship sr where sr.relatedFrom = :syn ";\r
-               if (taxon != null){\r
-                       hql += " and sr.relatedTo = :taxon";\r
-               }\r
-               Session session = this.getSession();\r
-               Query q = session.createQuery(hql);\r
-               \r
-               q.setParameter("syn", synonym);\r
-               if (taxon != null){\r
-                       q.setParameter("taxon", taxon);\r
-               }\r
-               long result = q.executeUpdate();\r
-               \r
-               return result;\r
-       }\r
-\r
-\r
-       @Override\r
-       public Integer countSynonymRelationships(TaxonBase taxonBase,\r
-                       SynonymRelationshipType type, Direction relatedfrom) {\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."+relatedfrom+" = :relatedSynonym");\r
-                   } else {\r
-                           query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom+" = :relatedSynonym and synonymRelationship.type = :type");\r
-                           query.setParameter("type",type);\r
-                   }\r
-                   query.setParameter("relatedTaxon", taxonBase);\r
-               \r
-                   return ((Long)query.uniqueResult()).intValue();\r
-               } else {\r
-                       AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
-                       query.add(AuditEntity.relatedId(relatedfrom.toString()).eq(taxonBase.getId()));\r
-                       query.addProjection(AuditEntity.id().count("id"));\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\r
-                       \r
-                       return ((Long)query.getSingleResult()).intValue();\r
-               }\r
-       }\r
-\r
-\r
-       @Override\r
-       public List<SynonymRelationship> getSynonymRelationships(TaxonBase taxonBase,\r
-                       SynonymRelationshipType type, Integer pageSize, Integer pageNumber,\r
-                       List<OrderHint> orderHints, List<String> propertyPaths,\r
-                       Direction direction) {\r
-               \r
-               AuditEvent auditEvent = getAuditEventFromContext();\r
-               if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
-                       Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
-            \r
-                       if (direction.equals(Direction.relatedTo)){\r
-                               criteria.add(Restrictions.eq("relatedTo", taxonBase));\r
-                       }else{\r
-                               criteria.add(Restrictions.eq("relatedFrom", taxonBase));\r
-                       }\r
-                   if(type != null) {\r
-                       criteria.add(Restrictions.eq("type", type));\r
-                   } \r
-               \r
+\r
+        for (SynonymRelationship synonymRelation:synonymRelationships){\r
+            TaxonNameBase synName;\r
+            NonViralName inferredSynName;\r
+            Synonym syn = synonymRelation.getSynonym();\r
+            HibernateProxyHelper.deproxy(syn);\r
+\r
+            synName = syn.getName();\r
+            ZoologicalName zooName = zooHashMap.get(synName.getUuid());\r
+            String synGenusName = zooName.getGenusOrUninomial();\r
+\r
+            switch(type.getId()){\r
+            case SynonymRelationshipType.INFERRED_EPITHET_OF().getId():\r
+                inferredSynName.setSpecificEpithet(addString);\r
+                break;\r
+            case SynonymRelationshipType.INFERRED_GENUS_OF().getId():\r
+                break;\r
+            case SynonymRelationshipType.POTENTIAL_COMBINATION_OF().getId():\r
+                break;\r
+            default:\r
+            }\r
+            if (!synonymsGenus.contains(synGenusName)){\r
+                synonymsGenus.add(synGenusName);\r
+            }\r
+            inferredSynName = NonViralName.NewInstance(Rank.SPECIES());\r
+            inferredSynName.setSpecificEpithet(epithetOfTaxon);\r
+            inferredSynName.setGenusOrUninomial(synGenusName);\r
+            inferredEpithet = Synonym.NewInstance(inferredSynName, null);\r
+            taxon.addSynonym(inferredEpithet, SynonymRelationshipType.INFERRED_GENUS_OF());\r
+            inferredSynonyms.add(inferredEpithet);\r
+            inferredSynName.generateTitle();\r
+            taxonNames.add(inferredSynName.getNameCache());\r
+        }\r
+\r
+\r
+        if (!taxonNames.isEmpty()){\r
+        List<String> synNotInCDM = this.taxaByNameNotInDB(taxonNames);\r
+        ZoologicalName name;\r
+        if (!synNotInCDM.isEmpty()){\r
+            for (Synonym syn :inferredSynonyms){\r
+                name =zooHashMap.get(syn.getName().getUuid());\r
+                if (!synNotInCDM.contains(name.getNameCache())){\r
+                    inferredSynonyms.remove(syn);\r
+                }\r
+            }\r
+        }\r
+        }\r
+    }*/\r
+\r
+    /*\r
+     * (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#countAllRelationships()\r
+     */\r
+    public int countAllRelationships() {\r
+        List<RelationshipBase> relationships = this.getAllRelationships(null, 0);\r
+        return relationships.size();\r
+    }\r
+\r
+\r
+    public List<String> taxaByNameNotInDB(List<String> taxonNames){\r
+        List<TaxonBase> notInDB = new ArrayList<TaxonBase>();\r
+        //get all taxa, already in db\r
+        Query query = getSession().createQuery("from TaxonNameBase t where t.nameCache IN (:taxonList)");\r
+        query.setParameterList("taxonList", taxonNames);\r
+        List<TaxonNameBase> taxaInDB = query.list();\r
+        //compare the original list with the result of the query\r
+        for (TaxonNameBase taxonName: taxaInDB){\r
+            if (taxonName.isInstanceOf(NonViralName.class)) {\r
+                NonViralName nonViralName = CdmBase.deproxy(taxonName, NonViralName.class);\r
+                String nameCache = nonViralName.getNameCache();\r
+                if (taxonNames.contains(nameCache)){\r
+                    taxonNames.remove(nameCache);\r
+                }\r
+            }\r
+        }\r
+\r
+        return taxonNames;\r
+    }\r
+\r
+    //TODO: mal nur mit UUID probieren (ohne fetch all properties), vielleicht geht das schneller?\r
+    public List<UUID> findIdenticalTaxonNameIds(List<String> propertyPaths){\r
+        Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");\r
+        List<UUID> zooNames = query.list();\r
+\r
+        return zooNames;\r
+\r
+    }\r
+\r
+    public List<TaxonNameBase> findIdenticalTaxonNames(List<String> propertyPaths) {\r
+\r
+        Query query=getSession().createQuery("select tmb2 from ZoologicalName tmb, ZoologicalName tmb2 fetch all properties where tmb.id != tmb2.id and tmb.nameCache = tmb2.nameCache");\r
+\r
+        List<TaxonNameBase> zooNames = query.list();\r
+\r
+        TaxonNameComparator taxComp = new TaxonNameComparator();\r
+        Collections.sort(zooNames, taxComp);\r
+\r
+        for (TaxonNameBase taxonNameBase: zooNames){\r
+            defaultBeanInitializer.initialize(taxonNameBase, propertyPaths);\r
+        }\r
+\r
+        return zooNames;\r
+    }\r
+\r
+    public List<TaxonNameBase> findIdenticalNamesNew(List<String> propertyPaths){\r
+\r
+        //Hole die beiden Source_ids von "Fauna Europaea" und "Erms" und in sources der names darf jeweils nur das entgegengesetzte auftreten (i member of tmb.taxonBases)\r
+        Query query = getSession().createQuery("Select id from Reference where titleCache like 'Fauna Europaea database'");\r
+        List<String> secRefFauna = query.list();\r
+        query = getSession().createQuery("Select id from Reference where titleCache like 'ERMS'");\r
+        List<String> secRefErms = query.list();\r
+        //Query query = getSession().createQuery("select tmb2.nameCache from ZoologicalName tmb, TaxonBase tb1, ZoologicalName tmb2, TaxonBase tb2 where tmb.id != tmb2.id and tb1.name = tmb and tb2.name = tmb2 and tmb.nameCache = tmb2.nameCache and tb1.sec != tb2.sec");\r
+        //Get all names of fauna europaea\r
+        query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefFauna");\r
+        query.setParameter("secRefFauna", secRefFauna.get(0));\r
+        List<String> namesFauna= query.list();\r
+\r
+        //Get all names of erms\r
+\r
+        query = getSession().createQuery("select zn.nameCache from ZoologicalName zn, TaxonBase tb where tb.name = zn and tb.sec.id = :secRefErms");\r
+        query.setParameter("secRefErms", secRefErms.get(0));\r
+\r
+        List<String> namesErms = query.list();\r
+        /*TaxonNameComparator comp = new TaxonNameComparator();\r
+        Collections.sort(namesFauna);\r
+        Collections.sort(namesErms);\r
+        */\r
+        List <String> identicalNames = new ArrayList<String>();\r
+        String predecessor = "";\r
+\r
+        for (String nameFauna: namesFauna){\r
+            if (namesErms.contains(nameFauna)){\r
+                identicalNames.add(nameFauna);\r
+            }\r
+        }\r
+\r
+\r
+        query = getSession().createQuery("from ZoologicalName zn where zn.nameCache IN (:identicalNames)");\r
+        query.setParameterList("identicalNames", identicalNames);\r
+        List<TaxonNameBase> result = query.list();\r
+        TaxonNameBase temp = result.get(0);\r
+\r
+        Iterator<OriginalSourceBase> sources = temp.getSources().iterator();\r
+\r
+        TaxonNameComparator taxComp = new TaxonNameComparator();\r
+        Collections.sort(result, taxComp);\r
+        defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+        return result;\r
+\r
+        }\r
+\r
+\r
+\r
+    public String getPhylumName(TaxonNameBase name){\r
+        List results = new ArrayList();\r
+        try{\r
+        Query query = getSession().createSQLQuery("select getPhylum("+ name.getId()+");");\r
+        results = query.list();\r
+        }catch(Exception e){\r
+            System.err.println(name.getUuid());\r
+            return null;\r
+        }\r
+        System.err.println("phylum of "+ name.getTitleCache() );\r
+        return (String)results.get(0);\r
+    }\r
+\r
+\r
+    public long countTaxaByCommonName(String searchString,\r
+            Classification classification, MatchMode matchMode,\r
+            Set<NamedArea> namedAreas) {\r
+        boolean doCount = true;\r
+        Query query = prepareTaxaByCommonName(searchString, classification, matchMode, namedAreas, null, null, doCount);\r
+        if (query != null && !query.list().isEmpty()) {\r
+            Object o = query.uniqueResult();\r
+            if(o != null) {\r
+                return (Long)o;\r
+            }\r
+        }\r
+        return 0;\r
+    }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#deleteSynonymRelationships(eu.etaxonomy.cdm.model.taxon.Synonym, eu.etaxonomy.cdm.model.taxon.Taxon)\r
+     */\r
+    public long deleteSynonymRelationships(Synonym synonym, Taxon taxon) {\r
+\r
+        String hql = "delete SynonymRelationship sr where sr.relatedFrom = :syn ";\r
+        if (taxon != null){\r
+            hql += " and sr.relatedTo = :taxon";\r
+        }\r
+        Session session = this.getSession();\r
+        Query q = session.createQuery(hql);\r
+\r
+        q.setParameter("syn", synonym);\r
+        if (taxon != null){\r
+            q.setParameter("taxon", taxon);\r
+        }\r
+        long result = q.executeUpdate();\r
+\r
+        return result;\r
+    }\r
+\r
+\r
+    @Override\r
+    public Integer countSynonymRelationships(TaxonBase taxonBase,\r
+            SynonymRelationshipType type, Direction relatedfrom) {\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."+relatedfrom+" = :relatedSynonym");\r
+            } else {\r
+                query = getSession().createQuery("select count(synonymRelationship) from SynonymRelationship synonymRelationship where synonymRelationship."+relatedfrom+" = :relatedSynonym and synonymRelationship.type = :type");\r
+                query.setParameter("type",type);\r
+            }\r
+            query.setParameter("relatedTaxon", taxonBase);\r
+\r
+            return ((Long)query.uniqueResult()).intValue();\r
+        } else {\r
+            AuditQuery query = getAuditReader().createQuery().forEntitiesAtRevision(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
+            query.add(AuditEntity.relatedId(relatedfrom.toString()).eq(taxonBase.getId()));\r
+            query.addProjection(AuditEntity.id().count("id"));\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\r
+\r
+            return ((Long)query.getSingleResult()).intValue();\r
+        }\r
+    }\r
+\r
+\r
+    @Override\r
+    public List<SynonymRelationship> getSynonymRelationships(TaxonBase taxonBase,\r
+            SynonymRelationshipType type, Integer pageSize, Integer pageNumber,\r
+            List<OrderHint> orderHints, List<String> propertyPaths,\r
+            Direction direction) {\r
+\r
+        AuditEvent auditEvent = getAuditEventFromContext();\r
+        if(auditEvent.equals(AuditEvent.CURRENT_VIEW)) {\r
+            Criteria criteria = getSession().createCriteria(SynonymRelationship.class);\r
+\r
+            if (direction.equals(Direction.relatedTo)){\r
+                criteria.add(Restrictions.eq("relatedTo", taxonBase));\r
+            }else{\r
+                criteria.add(Restrictions.eq("relatedFrom", taxonBase));\r
+            }\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(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
-                       \r
-                       if (direction.equals(Direction.relatedTo)){\r
-                               query.add(AuditEntity.relatedId("relatedTo").eq(taxonBase.getId()));\r
-                       }else{\r
-                               query.add(AuditEntity.relatedId("relatedFrom").eq(taxonBase.getId()));\r
-                       }\r
-                       \r
-                       if(type != null) {\r
-                               query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
-                   }\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
-                       List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
-                       defaultBeanInitializer.initializeAll(result, propertyPaths);\r
-                       \r
-                       // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
-                       // and we can't live without this functionality in CATE as it screws up the whole \r
-                       // taxon tree thing\r
-                       if(orderHints != null && !orderHints.isEmpty()) {\r
-                           SortedSet<SynonymRelationship> sortedList = new TreeSet<SynonymRelationship>(new SynonymRelationshipFromTaxonComparator());\r
-                           sortedList.addAll(result);\r
-                           return new ArrayList<SynonymRelationship>(sortedList);\r
-                       }\r
-                       \r
-                       return result;\r
-               }\r
-       }\r
-\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheTaxon()\r
-        */\r
-       @Override\r
-       public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheTaxon() {\r
-               String queryString = String.format("select uuid, titleCache from %s where DTYPE = '%s'", type.getSimpleName(), Taxon.class.getSimpleName());\r
-               Query query = getSession().createQuery(queryString);\r
-               \r
-               List<UuidAndTitleCache<TaxonBase>> result = getUuidAndTitleCache(query);\r
-               \r
-               return result;\r
-       }\r
-\r
-\r
-       /* (non-Javadoc)\r
-        * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheSynonym()\r
-        */\r
-       @Override\r
-       public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheSynonym() {\r
-               String queryString = String.format("select uuid, titleCache from %s where DTYPE = '%s'", type.getSimpleName(), Synonym.class.getSimpleName());\r
-               Query query = getSession().createQuery(queryString);\r
-               \r
-               List<UuidAndTitleCache<TaxonBase>> result = getUuidAndTitleCache(query);\r
-               \r
-               return result;\r
-       }\r
-\r
-\r
-\r
-\r
-       \r
-       \r
-       \r
-\r
-       \r
-       \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(TaxonRelationship.class,auditEvent.getRevisionNumber());\r
+\r
+            if (direction.equals(Direction.relatedTo)){\r
+                query.add(AuditEntity.relatedId("relatedTo").eq(taxonBase.getId()));\r
+            }else{\r
+                query.add(AuditEntity.relatedId("relatedFrom").eq(taxonBase.getId()));\r
+            }\r
+\r
+            if(type != null) {\r
+                query.add(AuditEntity.relatedId("type").eq(type.getId()));\r
+            }\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
+            List<SynonymRelationship> result = (List<SynonymRelationship>)query.getResultList();\r
+            defaultBeanInitializer.initializeAll(result, propertyPaths);\r
+\r
+            // Ugly, but for now, there is no way to sort on a related entity property in Envers,\r
+            // and we can't live without this functionality in CATE as it screws up the whole\r
+            // taxon tree thing\r
+            if(orderHints != null && !orderHints.isEmpty()) {\r
+                SortedSet<SynonymRelationship> sortedList = new TreeSet<SynonymRelationship>(new SynonymRelationshipFromTaxonComparator());\r
+                sortedList.addAll(result);\r
+                return new ArrayList<SynonymRelationship>(sortedList);\r
+            }\r
+\r
+            return result;\r
+        }\r
+    }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheTaxon()\r
+     */\r
+    @Override\r
+    public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheTaxon() {\r
+        String queryString = String.format("select uuid, titleCache from %s where DTYPE = '%s'", type.getSimpleName(), Taxon.class.getSimpleName());\r
+        Query query = getSession().createQuery(queryString);\r
+\r
+        List<UuidAndTitleCache<TaxonBase>> result = getUuidAndTitleCache(query);\r
+\r
+        return result;\r
+    }\r
+\r
+\r
+    /* (non-Javadoc)\r
+     * @see eu.etaxonomy.cdm.persistence.dao.taxon.ITaxonDao#getUuidAndTitleCacheSynonym()\r
+     */\r
+    @Override\r
+    public List<UuidAndTitleCache<TaxonBase>> getUuidAndTitleCacheSynonym() {\r
+        String queryString = String.format("select uuid, titleCache from %s where DTYPE = '%s'", type.getSimpleName(), Synonym.class.getSimpleName());\r
+        Query query = getSession().createQuery(queryString);\r
+\r
+        List<UuidAndTitleCache<TaxonBase>> result = getUuidAndTitleCache(query);\r
+\r
+        return result;\r
+    }\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
 }\r
index 3ec408e0e8587b7095e8253c49c4ac53e5e31142..44aaa9e5f79eb968c17ec2215b9b03e70d0d12f3 100644 (file)
@@ -1,51 +1,53 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns="http://www.springframework.org/schema/beans"
-       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
-       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
-       xsi:schemaLocation="http://www.springframework.org/schema/beans 
+  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
+  xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
+  xsi:schemaLocation="http://www.springframework.org/schema/beans
     http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
     http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
     http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
     ">
 
-       <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
-               <property name="sessionFactory" ref="sessionFactory" />
-       </bean>
-       
-       <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
-           <property name="namingStrategy">
-               <bean class="org.hibernate.cfg.DefaultComponentSafeNamingStrategy" />
-           </property>
-           
+  <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
+    <property name="sessionFactory" ref="sessionFactory" />
+  </bean>
+
+  <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
+      <property name="namingStrategy">
+        <bean class="org.hibernate.cfg.DefaultComponentSafeNamingStrategy" />
+      </property>
+
 <!--   <property name="entityInterceptor">
-               <bean class="eu.etaxonomy.cdm.persistence.hibernate.CdmHibernateInterceptor" />
-       </property>
-  -->      
-           <property name="configLocation" value="classpath:eu/etaxonomy/cdm/hibernate.cfg.xml"/>
-           <property  name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
-           <!--
+        <bean class="eu.etaxonomy.cdm.persistence.hibernate.CdmHibernateInterceptor" />
+      </property>
+  -->
+      <property name="configLocation" value="classpath:eu/etaxonomy/cdm/hibernate.cfg.xml"/>
+      <property  name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration"/>
+      <!--
             If dataSource is set, this will override corresponding settings in Hibernate properties.
-            If this is set, the Hibernate settings should not define a connection provider to 
+            If this is set, the Hibernate settings should not define a connection provider to
             avoid meaningless double configuration.
-            
+
             see also org.springframework.orm.hibernate3.AbstractSessionFactoryBean.setDataSource(DataSource dataSource)
-         --> 
-           <property name="dataSource" ref="dataSource"/>
-           <property name="hibernateProperties" ref="hibernateProperties"/>
-       </bean>
-       
-       <!-- 
-          Configuration for the BeanInitialization
-        -->
-       <bean id="titleCacheAutoInitializer" class="eu.etaxonomy.cdm.persistence.dao.TitleCacheAutoInitializer"></bean>
-       <bean id="defaultBeanInitializer" class="eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer">
-          <property name="beanAutoInitializers">
-              <map>
-                  <entry key="eu.etaxonomy.cdm.model.common.IdentifiableEntity"  value-ref="titleCacheAutoInitializer" />
-              </map>
-          </property>
-       </bean>
-       
-       
+         -->
+      <property name="dataSource" ref="dataSource"/>
+      <property name="hibernateProperties" ref="hibernateProperties"/>
+  </bean>
+
+  <!--
+     Configuration for the BeanInitialization
+   -->
+  <bean id="titleCacheAutoInitializer" class="eu.etaxonomy.cdm.persistence.dao.TitleCacheAutoInitializer"></bean>
+  <bean id="annotationTypeAutoInitializer" class="eu.etaxonomy.cdm.persistence.dao.AnnotationTypeAutoInitializer"></bean>
+  <bean id="defaultBeanInitializer" class="eu.etaxonomy.cdm.persistence.dao.hibernate.HibernateBeanInitializer">
+     <property name="beanAutoInitializers">
+         <map>
+             <entry key="eu.etaxonomy.cdm.model.common.IdentifiableEntity"  value-ref="titleCacheAutoInitializer" />
+             <entry key="eu.etaxonomy.cdm.model.common.Annotation"  value-ref="annotationTypeAutoInitializer" />
+         </map>
+     </property>
+  </bean>
+
+
 </beans>
index 663d4693f5a64c671148382aa09d02533fa69f1f..a7b326dc9b7b48fe327a94c7340872b7c0df1050 100644 (file)
       <entry key="eu.etaxonomy.cdm.model.common.TermBase">\r
         <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TermBaseBeanProcessor">\r
            <property name="excludes">\r
-                           <set value-type="java.lang.String">\r
-                               <value>partOf</value><!-- FIXME exclude partOf to avoid  lazy loading exceptions  -->\r
-                               <value>kindOf</value><!-- FIXME exclude kindOf to avoid  lazy loading exceptions  -->\r
-                               <value>infraGenericMarker</value><!-- FIXME leads to IllegalStateException if not excluded  -->\r
-                           </set>\r
-                       </property>\r
+             <set value-type="java.lang.String">\r
+                 <value>partOf</value><!-- FIXME exclude partOf to avoid  lazy loading exceptions  -->\r
+                 <value>kindOf</value><!-- FIXME exclude kindOf to avoid  lazy loading exceptions  -->\r
+                 <value>infraGenericMarker</value><!-- FIXME leads to IllegalStateException if not excluded  -->\r
+             </set>\r
+          </property>\r
         </bean>\r
-      </entry>\r
-      <entry key="eu.etaxonomy.cdm.model.description.TextData">\r
-        <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TextDataBeanProcessor" />\r
-      </entry>\r
-      <entry key="eu.etaxonomy.cdm.model.taxon.TaxonNode">\r
-        <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TaxonNodeBeanProcessor" />\r
-      </entry>\r
+        </entry>\r
+        <entry key="eu.etaxonomy.cdm.model.description.TextData">\r
+          <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TextDataBeanProcessor" />\r
+        </entry>\r
+        <entry key="eu.etaxonomy.cdm.model.taxon.TaxonNode">\r
+          <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TaxonNodeBeanProcessor" />\r
+        </entry>\r
         <entry key="eu.etaxonomy.cdm.model.reference.Reference">\r
             <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.ReferenceBaseBeanProcessor"/>\r
-          </entry>\r
-          <entry key="eu.etaxonomy.cdm.model.name.TypeDesignationBase">\r
-              <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TypeDesignationBaseBeanProcessor"/>\r
-            </entry>\r
-            <entry key="eu.etaxonomy.cdm.model.description.KeyStatement">\r
-                <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.KeyStatementBeanProcessor" />\r
-            </entry>\r
-            <entry key="eu.etaxonomy.cdm.model.agent.TeamOrPersonBase">\r
-                <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TeamOrPersonBaseBeanProcessor" />\r
-            </entry>\r
-\r
+        </entry>\r
+        <entry key="eu.etaxonomy.cdm.model.name.TypeDesignationBase">\r
+          <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TypeDesignationBaseBeanProcessor"/>\r
+        </entry>\r
+        <entry key="eu.etaxonomy.cdm.model.description.KeyStatement">\r
+            <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.KeyStatementBeanProcessor" />\r
+        </entry>\r
+        <entry key="eu.etaxonomy.cdm.model.agent.TeamOrPersonBase">\r
+            <bean class="eu.etaxonomy.cdm.remote.json.processor.bean.TeamOrPersonBaseBeanProcessor" />\r
+        </entry>\r
       </map>\r
     </property>\r
     <property name="jsonPropertyFilter">\r
-            <bean class="net.sf.json.filters.OrPropertyFilter">\r
-              <constructor-arg>\r
-                  <bean class="eu.etaxonomy.cdm.remote.json.util.InitializedHibernatePropertyFilter" />\r
-              </constructor-arg>\r
-              <constructor-arg ref="genericApiCardinalityPropertyFilter">\r
-              </constructor-arg>\r
-            </bean>\r
-        </property>\r
+        <bean class="net.sf.json.filters.OrPropertyFilter">\r
+          <constructor-arg>\r
+              <bean class="eu.etaxonomy.cdm.remote.json.util.InitializedHibernatePropertyFilter" />\r
+          </constructor-arg>\r
+          <constructor-arg ref="genericApiCardinalityPropertyFilter">\r
+          </constructor-arg>\r
+        </bean>\r
+    </property>\r
     <property name="jsonValueProcessors">\r
       <map>\r
         <entry key="org.hibernate.proxy.HibernateProxy">\r
       </map>\r
     </property>\r
     <property name="jsonPropertyFilter">\r
-            <bean class="net.sf.json.filters.OrPropertyFilter">\r
-              <constructor-arg>\r
-                  <bean class="eu.etaxonomy.cdm.remote.json.util.InitializedHibernatePropertyFilter" />\r
-              </constructor-arg>\r
-              <constructor-arg ref="genericApiCardinalityPropertyFilter">\r
-              </constructor-arg>\r
-            </bean>\r
-        </property>\r
+      <bean class="net.sf.json.filters.OrPropertyFilter">\r
+        <constructor-arg>\r
+            <bean class="eu.etaxonomy.cdm.remote.json.util.InitializedHibernatePropertyFilter" />\r
+        </constructor-arg>\r
+        <constructor-arg ref="genericApiCardinalityPropertyFilter">\r
+        </constructor-arg>\r
+      </bean>\r
+    </property>\r
     <property name="jsonValueProcessors">\r
       <map>\r
         <entry key="org.hibernate.proxy.HibernateProxy">\r
           <bean\r
             class="eu.etaxonomy.cdm.remote.json.processor.value.ClassJSONValueProcessor" />\r
         </entry>\r
-                <entry key="java.util.Map">\r
-                    <bean class="eu.etaxonomy.cdm.remote.json.processor.value.MapJSONValueProcessor" />\r
-                </entry>\r
-                <entry key="java.net.URI">\r
-                    <bean class="eu.etaxonomy.cdm.remote.json.processor.value.URIJSONValueProcessor"/>\r
-                </entry>\r
+        <entry key="java.util.Map">\r
+            <bean class="eu.etaxonomy.cdm.remote.json.processor.value.MapJSONValueProcessor" />\r
+        </entry>\r
+        <entry key="java.net.URI">\r
+            <bean class="eu.etaxonomy.cdm.remote.json.processor.value.URIJSONValueProcessor"/>\r
+        </entry>\r
       </map>\r
     </property>\r
     <property name="ignoreDefaultExcludes" value="true" />\r
           <bean\r
             class="eu.etaxonomy.cdm.remote.json.processor.bean.TermBaseBeanProcessor">\r
             <property name="replaceRepresentations" value="true" />\r
-              <property name="excludes">\r
-                            <set value-type="java.lang.String">\r
-                                <value>infraGenericMarker</value><!-- FIXME leads to IllegalStateException if not excluded  -->\r
-                                <value>partOf</value><!-- DefinedTermBase -->\r
-                        <value>kindOf</value><!-- DefinedTermBase -->\r
-                        <value>includes</value><!-- DefinedTermBase -->\r
-                        <value>generalizationOf</value><!-- DefinedTermBase -->\r
-                        <value>vocabulary</value><!-- DefinedTermBase -->\r
-                        <!--\r
-                            FIXME must exclude partOf, kindOf, includes, generalizationOf .. to\r
-                            avoid class cast or lazy loading exceptions in TDWG Areas\r
-                        -->\r
-                            </set>\r
-                        </property>\r
+            <property name="excludes">\r
+                <set value-type="java.lang.String">\r
+                  <value>infraGenericMarker</value><!-- FIXME leads to IllegalStateException if not excluded  -->\r
+                  <value>partOf</value><!-- DefinedTermBase -->\r
+                  <value>kindOf</value><!-- DefinedTermBase -->\r
+                  <value>includes</value><!-- DefinedTermBase -->\r
+                  <value>generalizationOf</value><!-- DefinedTermBase -->\r
+                  <value>vocabulary</value><!-- DefinedTermBase -->\r
+                  <!--\r
+                      FIXME must exclude partOf, kindOf, includes, generalizationOf .. to\r
+                      avoid class cast or lazy loading exceptions in TDWG Areas\r
+                  -->\r
+                </set>\r
+            </property>\r
           </bean>\r
         </entry>\r
         <entry key="eu.etaxonomy.cdm.model.description.TextData">\r