refactory: added UI removed from core plugin.
[phpeclipse.git] / net.sourceforge.phpeclipse.ui / src / net / sourceforge / phpdt / internal / ui / text / spelling / engine / DefaultPhoneticHashProvider.java
diff --git a/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticHashProvider.java b/net.sourceforge.phpeclipse.ui/src/net/sourceforge/phpdt/internal/ui/text/spelling/engine/DefaultPhoneticHashProvider.java
new file mode 100644 (file)
index 0000000..2229bcf
--- /dev/null
@@ -0,0 +1,852 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+
+package net.sourceforge.phpdt.internal.ui.text.spelling.engine;
+
+/**
+ * Default phonetic hash provider for english languages.
+ * <p>
+ * This algorithm uses an adapted version double metaphone algorithm by Lawrence
+ * Philips.
+ * <p>
+ * 
+ * @since 3.0
+ */
+public final class DefaultPhoneticHashProvider implements IPhoneticHashProvider {
+
+       private static final String[] meta01 = { "ACH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta02 = { "BACHER", "MACHER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta03 = { "CAESAR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta04 = { "CHIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta05 = { "CH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta06 = { "CHAE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta07 = { "HARAC", "HARIS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta08 = { "HOR", "HYM", "HIA", "HEM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta09 = { "CHORE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta10 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta11 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta12 = { "ORCHES", "ARCHIT", "ORCHID", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta13 = { "T", "S", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta14 = { "A", "O", "U", "E", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta15 = {
+                       "L", "R", "N", "M", "B", "H", "F", "V", "W", " ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$
+
+       private static final String[] meta16 = { "MC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta17 = { "CZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta18 = { "WICZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta19 = { "CIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta20 = { "CC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta21 = { "I", "E", "H", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta22 = { "HU", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta23 = { "UCCEE", "UCCES", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta24 = { "CK", "CG", "CQ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta25 = { "CI", "CE", "CY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta26 = { "GN", "KN", "PN", "WR", "PS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
+       private static final String[] meta27 = { " C", " Q", " G", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta28 = { "C", "K", "Q", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta29 = { "CE", "CI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta30 = { "DG", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta31 = { "I", "E", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta32 = { "DT", "DD", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta33 = { "B", "H", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta34 = { "B", "H", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta35 = { "B", "H", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta36 = { "C", "G", "L", "R", "T", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+
+       private static final String[] meta37 = { "EY", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta38 = { "LI", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta39 = {
+                       "ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$ //$NON-NLS-11$ //$NON-NLS-12$
+
+       private static final String[] meta40 = { "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta41 = { "DANGER", "RANGER", "MANGER", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta42 = { "E", "I", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta43 = { "RGY", "OGY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta44 = { "E", "I", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta45 = { "AGGI", "OGGI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta46 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta47 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta48 = { "ET", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta49 = { "C", "X", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta50 = { "JOSE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta51 = { "SAN ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta52 = { "SAN ", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta53 = { "JOSE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta54 = {
+                       "L", "T", "K", "S", "N", "M", "B", "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$
+
+       private static final String[] meta55 = { "S", "K", "L", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta56 = { "ILLO", "ILLA", "ALLE", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta57 = { "AS", "OS", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta58 = { "A", "O", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta59 = { "ALLE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta60 = { "UMB", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta61 = { "ER", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta62 = { "P", "B", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta63 = { "IE", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta64 = { "ME", "MA", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta65 = { "ISL", "YSL", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta66 = { "SUGAR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta67 = { "SH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta68 = { "HEIM", "HOEK", "HOLM", "HOLZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta69 = { "SIO", "SIA", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta70 = { "SIAN", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta71 = { "M", "N", "L", "W", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta72 = { "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta73 = { "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta74 = { "SC", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta75 = {
+                       "OO", "ER", "EN", "UY", "ED", "EM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
+
+       private static final String[] meta76 = { "ER", "EN", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta77 = { "I", "E", "Y", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       private static final String[] meta78 = { "AI", "OI", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta79 = { "S", "Z", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta80 = { "TION", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta81 = { "TIA", "TCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta82 = { "TH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta83 = { "TTH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta84 = { "OM", "AM", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta85 = { "VAN ", "VON ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta86 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta87 = { "T", "D", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta88 = { "WR", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta89 = { "WH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta90 = {
+                       "EWSKI", "EWSKY", "OWSKI", "OWSKY", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+
+       private static final String[] meta91 = { "SCH", "" }; //$NON-NLS-1$ //$NON-NLS-2$
+
+       private static final String[] meta92 = { "WICZ", "WITZ", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta93 = { "IAU", "EAU", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta94 = { "AU", "OU", "" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+       private static final String[] meta95 = { "W", "K", "CZ", "WITZ" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+
+       /** The mutator characters */
+       private static final char[] MUTATOR_CHARACTERS = { 'A', 'B', 'X', 'S', 'K',
+                       'J', 'T', 'F', 'H', 'L', 'M', 'N', 'P', 'R', '0' };
+
+       /** The vowel characters */
+       private static final char[] VOWEL_CHARACTERS = new char[] { 'A', 'E', 'I',
+                       'O', 'U', 'Y' };
+
+       /**
+        * Test whether the specified string contains one of the candidates in the
+        * list.
+        * 
+        * @param candidates
+        *            Array of candidates to check
+        * @param token
+        *            The token to check for occurrences of the candidates
+        * @param offset
+        *            The offset where to begin checking in the string
+        * @param length
+        *            The length of the range in the string to check
+        * @return <code>true</code> iff the string contains one of the
+        *         candidates, <code>false</code> otherwise.
+        */
+       protected static final boolean hasOneOf(final String[] candidates,
+                       final char[] token, final int offset, final int length) {
+
+               if (offset < 0 || offset >= token.length || candidates.length == 0)
+                       return false;
+
+               final String checkable = new String(token, offset, length);
+               for (int index = 0; index < candidates.length; index++) {
+
+                       if (candidates[index].equals(checkable))
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Test whether the specified token contains one of the candidates in the
+        * list.
+        * 
+        * @param candidates
+        *            Array of candidates to check
+        * @param token
+        *            The token to check for occurrences of the candidates
+        * @return <code>true</code> iff the string contains one of the
+        *         candidates, <code>false</code> otherwise.
+        */
+       protected static final boolean hasOneOf(final String[] candidates,
+                       final String token) {
+
+               for (int index = 0; index < candidates.length; index++) {
+
+                       if (token.indexOf(candidates[index]) >= 0)
+                               return true;
+               }
+               return false;
+       }
+
+       /**
+        * Tests whether the specified token contains a vowel at the specified
+        * offset.
+        * 
+        * @param token
+        *            The token to check for a vowel
+        * @param offset
+        *            The offset where to begin checking in the token
+        * @param length
+        *            The length of the range in the token to check
+        * @return <code>true</code> iff the token contains a vowel,
+        *         <code>false</code> otherwise.
+        */
+       protected static final boolean hasVowel(final char[] token,
+                       final int offset, final int length) {
+
+               if (offset >= 0 && offset < length) {
+
+                       final char character = token[offset];
+                       for (int index = 0; index < VOWEL_CHARACTERS.length; index++) {
+
+                               if (VOWEL_CHARACTERS[index] == character)
+                                       return true;
+                       }
+               }
+               return false;
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.IPhoneticHasher#getHash(java.lang.String)
+        */
+       public final String getHash(final String word) {
+
+               final String input = word.toUpperCase() + "     "; //$NON-NLS-1$
+               final char[] hashable = input.toCharArray();
+
+               final boolean has95 = hasOneOf(meta95, input);
+               final StringBuffer buffer = new StringBuffer(hashable.length);
+
+               int offset = 0;
+               if (hasOneOf(meta26, hashable, 0, 2))
+                       offset += 1;
+
+               if (hashable[0] == 'X') {
+                       buffer.append('S');
+                       offset += 1;
+               }
+
+               while (offset < hashable.length) {
+
+                       switch (hashable[offset]) {
+                       case 'A':
+                       case 'E':
+                       case 'I':
+                       case 'O':
+                       case 'U':
+                       case 'Y':
+                               if (offset == 0)
+                                       buffer.append('A');
+                               offset += 1;
+                               break;
+                       case 'B':
+                               buffer.append('P');
+                               if (hashable[offset + 1] == 'B')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'C':
+                               if ((offset > 1)
+                                               && !hasVowel(hashable, offset - 2, hashable.length)
+                                               && hasOneOf(meta01, hashable, (offset - 1), 3)
+                                               && (hashable[offset + 2] != 'I')
+                                               && (hashable[offset + 2] != 'E')
+                                               || hasOneOf(meta02, hashable, (offset - 2), 6)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0) && hasOneOf(meta03, hashable, offset, 6)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta04, hashable, offset, 4)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta05, hashable, offset, 2)) {
+                                       if ((offset > 0) && hasOneOf(meta06, hashable, offset, 4)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if ((offset == 0)
+                                                       && hasOneOf(meta07, hashable, (offset + 1), 5)
+                                                       || hasOneOf(meta08, hashable, offset + 1, 3)
+                                                       && !hasOneOf(meta09, hashable, 0, 5)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if (hasOneOf(meta10, hashable, 0, 4)
+                                                       || hasOneOf(meta11, hashable, 0, 3)
+                                                       || hasOneOf(meta12, hashable, offset - 2, 6)
+                                                       || hasOneOf(meta13, hashable, offset + 2, 1)
+                                                       || (hasOneOf(meta14, hashable, offset - 1, 1) || (offset == 0))
+                                                       && hasOneOf(meta15, hashable, offset + 2, 1)) {
+                                               buffer.append('K');
+                                       } else {
+                                               if (offset > 0) {
+                                                       if (hasOneOf(meta16, hashable, 0, 2))
+                                                               buffer.append('K');
+                                                       else
+                                                               buffer.append('X');
+                                               } else {
+                                                       buffer.append('X');
+                                               }
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta17, hashable, offset, 2)
+                                               && !hasOneOf(meta18, hashable, offset, 4)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta19, hashable, offset, 2)) {
+                                       buffer.append('X');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta20, hashable, offset, 2)
+                                               && !((offset == 1) && hashable[0] == 'M')) {
+                                       if (hasOneOf(meta21, hashable, offset + 2, 1)
+                                                       && !hasOneOf(meta22, hashable, offset + 2, 2)) {
+                                               if (((offset == 1) && (hashable[offset - 1] == 'A'))
+                                                               || hasOneOf(meta23, hashable, (offset - 1), 5))
+                                                       buffer.append("KS"); //$NON-NLS-1$
+                                               else
+                                                       buffer.append('X');
+                                               offset += 3;
+                                               break;
+                                       } else {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               if (hasOneOf(meta24, hashable, offset, 2)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               } else if (hasOneOf(meta25, hashable, offset, 2)) {
+                                       buffer.append('S');
+                                       offset += 2;
+                                       break;
+                               }
+                               buffer.append('K');
+                               if (hasOneOf(meta27, hashable, offset + 1, 2))
+                                       offset += 3;
+                               else if (hasOneOf(meta28, hashable, offset + 1, 1)
+                                               && !hasOneOf(meta29, hashable, offset + 1, 2))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case '\u00C7':
+                               buffer.append('S');
+                               offset += 1;
+                               break;
+                       case 'D':
+                               if (hasOneOf(meta30, hashable, offset, 2)) {
+                                       if (hasOneOf(meta31, hashable, offset + 2, 1)) {
+                                               buffer.append('J');
+                                               offset += 3;
+                                               break;
+                                       } else {
+                                               buffer.append("TK"); //$NON-NLS-1$
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               buffer.append('T');
+                               if (hasOneOf(meta32, hashable, offset, 2)) {
+                                       offset += 2;
+                               } else {
+                                       offset += 1;
+                               }
+                               break;
+                       case 'F':
+                               if (hashable[offset + 1] == 'F')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('F');
+                               break;
+                       case 'G':
+                               if (hashable[offset + 1] == 'H') {
+                                       if ((offset > 0)
+                                                       && !hasVowel(hashable, offset - 1, hashable.length)) {
+                                               buffer.append('K');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       if (offset < 3) {
+                                               if (offset == 0) {
+                                                       if (hashable[offset + 2] == 'I')
+                                                               buffer.append('J');
+                                                       else
+                                                               buffer.append('K');
+                                                       offset += 2;
+                                                       break;
+                                               }
+                                       }
+                                       if ((offset > 1)
+                                                       && hasOneOf(meta33, hashable, offset - 2, 1)
+                                                       || ((offset > 2) && hasOneOf(meta34, hashable,
+                                                                       offset - 3, 1))
+                                                       || ((offset > 3) && hasOneOf(meta35, hashable,
+                                                                       offset - 4, 1))) {
+                                               offset += 2;
+                                               break;
+                                       } else {
+                                               if ((offset > 2) && (hashable[offset - 1] == 'U')
+                                                               && hasOneOf(meta36, hashable, offset - 3, 1)) {
+                                                       buffer.append('F');
+                                               } else {
+                                                       if ((offset > 0) && (hashable[offset - 1] != 'I'))
+                                                               buffer.append('K');
+                                               }
+                                               offset += 2;
+                                               break;
+                                       }
+                               }
+                               if (hashable[offset + 1] == 'N') {
+                                       if ((offset == 1) && hasVowel(hashable, 0, hashable.length)
+                                                       && !has95) {
+                                               buffer.append("KN"); //$NON-NLS-1$
+                                       } else {
+                                               if (!hasOneOf(meta37, hashable, offset + 2, 2)
+                                                               && (hashable[offset + 1] != 'Y') && !has95) {
+                                                       buffer.append("N"); //$NON-NLS-1$
+                                               } else {
+                                                       buffer.append("KN"); //$NON-NLS-1$
+                                               }
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta38, hashable, offset + 1, 2) && !has95) {
+                                       buffer.append("KL"); //$NON-NLS-1$
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0)
+                                               && ((hashable[offset + 1] == 'Y') || hasOneOf(meta39,
+                                                               hashable, offset + 1, 2))) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((hasOneOf(meta40, hashable, offset + 1, 2) || (hashable[offset + 1] == 'Y'))
+                                               && !hasOneOf(meta41, hashable, 0, 6)
+                                               && !hasOneOf(meta42, hashable, offset - 1, 1)
+                                               && !hasOneOf(meta43, hashable, offset - 1, 3)) {
+                                       buffer.append('K');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta44, hashable, offset + 1, 1)
+                                               || hasOneOf(meta45, hashable, offset - 1, 4)) {
+                                       if (hasOneOf(meta46, hashable, 0, 4)
+                                                       || hasOneOf(meta47, hashable, 0, 3)
+                                                       || hasOneOf(meta48, hashable, offset + 1, 2)) {
+                                               buffer.append('K');
+                                       } else {
+                                               buffer.append('J');
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hashable[offset + 1] == 'G')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'H':
+                               if (((offset == 0) || hasVowel(hashable, offset - 1,
+                                               hashable.length))
+                                               && hasVowel(hashable, offset + 1, hashable.length)) {
+                                       buffer.append('H');
+                                       offset += 2;
+                               } else {
+                                       offset += 1;
+                               }
+                               break;
+                       case 'J':
+                               if (hasOneOf(meta50, hashable, offset, 4)
+                                               || hasOneOf(meta51, hashable, 0, 4)) {
+                                       if ((offset == 0) && (hashable[offset + 4] == ' ')
+                                                       || hasOneOf(meta52, hashable, 0, 4)) {
+                                               buffer.append('H');
+                                       } else {
+                                               buffer.append('J');
+                                       }
+                                       offset += 1;
+                                       break;
+                               }
+                               if ((offset == 0) && !hasOneOf(meta53, hashable, offset, 4)) {
+                                       buffer.append('J');
+                               } else {
+                                       if (hasVowel(hashable, offset - 1, hashable.length)
+                                                       && !has95
+                                                       && ((hashable[offset + 1] == 'A') || hashable[offset + 1] == 'O')) {
+                                               buffer.append('J');
+                                       } else {
+                                               if (offset == (hashable.length - 1)) {
+                                                       buffer.append('J');
+                                               } else {
+                                                       if (!hasOneOf(meta54, hashable, offset + 1, 1)
+                                                                       && !hasOneOf(meta55, hashable, offset - 1,
+                                                                                       1)) {
+                                                               buffer.append('J');
+                                                       }
+                                               }
+                                       }
+                               }
+                               if (hashable[offset + 1] == 'J')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'K':
+                               if (hashable[offset + 1] == 'K')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'L':
+                               if (hashable[offset + 1] == 'L') {
+                                       if (((offset == (hashable.length - 3)) && hasOneOf(meta56,
+                                                       hashable, offset - 1, 4))
+                                                       || ((hasOneOf(meta57, hashable,
+                                                                       (hashable.length - 1) - 1, 2) || hasOneOf(
+                                                                       meta58, hashable, hashable.length - 1, 1)) && hasOneOf(
+                                                                       meta59, hashable, offset - 1, 4))) {
+                                               buffer.append('L');
+                                               offset += 2;
+                                               break;
+                                       }
+                                       offset += 2;
+                               } else
+                                       offset += 1;
+                               buffer.append('L');
+                               break;
+                       case 'M':
+                               if ((hasOneOf(meta60, hashable, offset - 1, 3) && (((offset + 1) == (hashable.length - 1)) || hasOneOf(
+                                               meta61, hashable, offset + 2, 2)))
+                                               || (hashable[offset + 1] == 'M'))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('M');
+                               break;
+                       case 'N':
+                               if (hashable[offset + 1] == 'N')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('N');
+                               break;
+                       case '\u00D1':
+                               offset += 1;
+                               buffer.append('N');
+                               break;
+                       case 'P':
+                               if (hashable[offset + 1] == 'N') {
+                                       buffer.append('F');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta62, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('P');
+                               break;
+                       case 'Q':
+                               if (hashable[offset + 1] == 'Q')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('K');
+                               break;
+                       case 'R':
+                               if (!((offset == (hashable.length - 1)) && !has95
+                                               && hasOneOf(meta63, hashable, offset - 2, 2) && !hasOneOf(
+                                               meta64, hashable, offset - 4, 2)))
+                                       buffer.append('R');
+                               if (hashable[offset + 1] == 'R')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'S':
+                               if (hasOneOf(meta65, hashable, offset - 1, 3)) {
+                                       offset += 1;
+                                       break;
+                               }
+                               if ((offset == 0) && hasOneOf(meta66, hashable, offset, 5)) {
+                                       buffer.append('X');
+                                       offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta67, hashable, offset, 2)) {
+                                       if (hasOneOf(meta68, hashable, offset + 1, 4))
+                                               buffer.append('S');
+                                       else
+                                               buffer.append('X');
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta69, hashable, offset, 3)
+                                               || hasOneOf(meta70, hashable, offset, 4)) {
+                                       buffer.append('S');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (((offset == 0) && hasOneOf(meta71, hashable, offset + 1, 1))
+                                               || hasOneOf(meta72, hashable, offset + 1, 1)) {
+                                       buffer.append('S');
+                                       if (hasOneOf(meta73, hashable, offset + 1, 1))
+                                               offset += 2;
+                                       else
+                                               offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta74, hashable, offset, 2)) {
+                                       if (hashable[offset + 2] == 'H')
+                                               if (hasOneOf(meta75, hashable, offset + 3, 2)) {
+                                                       if (hasOneOf(meta76, hashable, offset + 3, 2)) {
+                                                               buffer.append("X"); //$NON-NLS-1$
+                                                       } else {
+                                                               buffer.append("SK"); //$NON-NLS-1$
+                                                       }
+                                                       offset += 3;
+                                                       break;
+                                               } else {
+                                                       buffer.append('X');
+                                                       offset += 3;
+                                                       break;
+                                               }
+                                       if (hasOneOf(meta77, hashable, offset + 2, 1)) {
+                                               buffer.append('S');
+                                               offset += 3;
+                                               break;
+                                       }
+                                       buffer.append("SK"); //$NON-NLS-1$
+                                       offset += 3;
+                                       break;
+                               }
+                               if (!((offset == (hashable.length - 1)) && hasOneOf(meta78,
+                                               hashable, offset - 2, 2)))
+                                       buffer.append('S');
+                               if (hasOneOf(meta79, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'T':
+                               if (hasOneOf(meta80, hashable, offset, 4)) {
+                                       buffer.append('X');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (hasOneOf(meta81, hashable, offset, 3)) {
+                                       buffer.append('X');
+                                       offset += 3;
+                                       break;
+                               }
+                               if (hasOneOf(meta82, hashable, offset, 2)
+                                               || hasOneOf(meta83, hashable, offset, 3)) {
+                                       if (hasOneOf(meta84, hashable, (offset + 2), 2)
+                                                       || hasOneOf(meta85, hashable, 0, 4)
+                                                       || hasOneOf(meta86, hashable, 0, 3)) {
+                                               buffer.append('T');
+                                       } else {
+                                               buffer.append('0');
+                                       }
+                                       offset += 2;
+                                       break;
+                               }
+                               if (hasOneOf(meta87, hashable, offset + 1, 1)) {
+                                       offset += 2;
+                               } else
+                                       offset += 1;
+                               buffer.append('T');
+                               break;
+                       case 'V':
+                               if (hashable[offset + 1] == 'V')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               buffer.append('F');
+                               break;
+                       case 'W':
+                               if (hasOneOf(meta88, hashable, offset, 2)) {
+                                       buffer.append('R');
+                                       offset += 2;
+                                       break;
+                               }
+                               if ((offset == 0)
+                                               && (hasVowel(hashable, offset + 1, hashable.length) || hasOneOf(
+                                                               meta89, hashable, offset, 2))) {
+                                       buffer.append('A');
+                               }
+                               if (((offset == (hashable.length - 1)) && hasVowel(hashable,
+                                               offset - 1, hashable.length))
+                                               || hasOneOf(meta90, hashable, offset - 1, 5)
+                                               || hasOneOf(meta91, hashable, 0, 3)) {
+                                       buffer.append('F');
+                                       offset += 1;
+                                       break;
+                               }
+                               if (hasOneOf(meta92, hashable, offset, 4)) {
+                                       buffer.append("TS"); //$NON-NLS-1$
+                                       offset += 4;
+                                       break;
+                               }
+                               offset += 1;
+                               break;
+                       case 'X':
+                               if (!((offset == (hashable.length - 1)) && (hasOneOf(meta93,
+                                               hashable, offset - 3, 3) || hasOneOf(meta94, hashable,
+                                               offset - 2, 2))))
+                                       buffer.append("KS"); //$NON-NLS-1$
+                               if (hasOneOf(meta49, hashable, offset + 1, 1))
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       case 'Z':
+                               if (hashable[offset + 1] == 'H') {
+                                       buffer.append('J');
+                                       offset += 2;
+                                       break;
+                               } else {
+                                       buffer.append('S');
+                               }
+                               if (hashable[offset + 1] == 'Z')
+                                       offset += 2;
+                               else
+                                       offset += 1;
+                               break;
+                       default:
+                               offset += 1;
+                       }
+               }
+               return buffer.toString();
+       }
+
+       /*
+        * @see org.eclipse.spelling.done.IPhoneticHasher#getMutators()
+        */
+       public final char[] getMutators() {
+               return MUTATOR_CHARACTERS;
+       }
+}