Initial revision
[old-projects.git] / ekit / com / swabunga / spell / engine / DoubleMeta.java
diff --git a/ekit/com/swabunga/spell/engine/DoubleMeta.java b/ekit/com/swabunga/spell/engine/DoubleMeta.java
new file mode 100644 (file)
index 0000000..d9a3a63
--- /dev/null
@@ -0,0 +1,908 @@
+/* This class is based on Lawrence Phillips original c++ code for this class.\r\r
+ * Found here: http://aspell.sourceforge.net/metaphone/\r\r
+ *\r\r
+ */\r\r
+\r\r
+\r\r
+package  com.swabunga.spell.engine;\r\r
+\r\r
+\r\r
+/**\r\r
+ * Double Meta class\r\r
+ * <p>\r\r
+ * Things that were changed:\r\r
+ *   The alternate flag could be set to true but was never checked so why bother with it. REMOVED\r\r
+ *   Why was this class serializable?\r\r
+ *   The primary, in, length and last variables could be initialized and local to the\r\r
+ *   process method and references passed arround the appropriate methods. As such there are\r\r
+ *   no class variables and this class becomes firstly threadsafe and secondly could be static final.\r\r
+ *   The function call SlavoGermaic was called repeatedly in the process function, it is now only called once.\r\r
+ *\r\r
+ */\r\r
+class DoubleMeta implements Transformator{\r\r
+\r\r
+    private static final String[] myList = {\r\r
+        "GN", "KN", "PN", "WR", "PS", ""\r\r
+    };\r\r
+    private static final String[] list1 = {\r\r
+        "ACH", ""\r\r
+    };\r\r
+    private static final String[] list2 = {\r\r
+        "BACHER", "MACHER", ""\r\r
+    };\r\r
+    private static final String[] list3 = {\r\r
+        "CAESAR", ""\r\r
+    };\r\r
+    private static final String[] list4 = {\r\r
+        "CHIA", ""\r\r
+    };\r\r
+    private static final String[] list5 = {\r\r
+        "CH", ""\r\r
+    };\r\r
+    private static final String[] list6 = {\r\r
+        "CHAE", ""\r\r
+    };\r\r
+    private static final String[] list7 = {\r\r
+        "HARAC", "HARIS", ""\r\r
+    };\r\r
+    private static final String[] list8 = {\r\r
+        "HOR", "HYM", "HIA", "HEM", ""\r\r
+    };\r\r
+    private static final String[] list9 = {\r\r
+        "CHORE", ""\r\r
+    };\r\r
+    private static final String[] list10 = {\r\r
+        "VAN ", "VON ", ""\r\r
+    };\r\r
+    private static final String[] list11 = {\r\r
+        "SCH", ""\r\r
+    };\r\r
+    private static final String[] list12 = {\r\r
+        "ORCHES", "ARCHIT", "ORCHID", ""\r\r
+    };\r\r
+    private static final String[] list13 = {\r\r
+        "T", "S", ""\r\r
+    };\r\r
+    private static final String[] list14 = {\r\r
+        "A", "O", "U", "E", ""\r\r
+    };\r\r
+    private static final String[] list15 = {\r\r
+        "L", "R", "N", "M", "B", "H", "F", "V", "W", " ", ""\r\r
+    };\r\r
+    private static final String[] list16 = {\r\r
+        "MC", ""\r\r
+    };\r\r
+    private static final String[] list17 = {\r\r
+        "CZ", ""\r\r
+    };\r\r
+    private static final String[] list18 = {\r\r
+        "WICZ", ""\r\r
+    };\r\r
+    private static final String[] list19 = {\r\r
+        "CIA", ""\r\r
+    };\r\r
+    private static final String[] list20 = {\r\r
+        "CC", ""\r\r
+    };\r\r
+    private static final String[] list21 = {\r\r
+        "I", "E", "H", ""\r\r
+    };\r\r
+    private static final String[] list22 = {\r\r
+        "HU", ""\r\r
+    };\r\r
+    private static final String[] list23 = {\r\r
+        "UCCEE", "UCCES", ""\r\r
+    };\r\r
+    private static final String[] list24 = {\r\r
+        "CK", "CG", "CQ", ""\r\r
+    };\r\r
+    private static final String[] list25 = {\r\r
+        "CI", "CE", "CY", ""\r\r
+    };\r\r
+    private static final String[] list26 = {\r\r
+        "CIO", "CIE", "CIA", ""\r\r
+    };\r\r
+    private static final String[] list27 = {\r\r
+        " C", " Q", " G", ""\r\r
+    };\r\r
+    private static final String[] list28 = {\r\r
+        "C", "K", "Q", ""\r\r
+    };\r\r
+    private static final String[] list29 = {\r\r
+        "CE", "CI", ""\r\r
+    };\r\r
+    private static final String[] list30 = {\r\r
+        "DG", ""\r\r
+    };\r\r
+    private static final String[] list31 = {\r\r
+        "I", "E", "Y", ""\r\r
+    };\r\r
+    private static final String[] list32 = {\r\r
+        "DT", "DD", ""\r\r
+    };\r\r
+    private static final String[] list33 = {\r\r
+        "B", "H", "D", ""\r\r
+    };\r\r
+    private static final String[] list34 = {\r\r
+        "B", "H", "D", ""\r\r
+    };\r\r
+    private static final String[] list35 = {\r\r
+        "B", "H", ""\r\r
+    };\r\r
+    private static final String[] list36 = {\r\r
+        "C", "G", "L", "R", "T", ""\r\r
+    };\r\r
+    private static final String[] list37 = {\r\r
+        "EY", ""\r\r
+    };\r\r
+    private static final String[] list38 = {\r\r
+        "LI", ""\r\r
+    };\r\r
+    private static final String[] list39 = {\r\r
+        "ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER",\r\r
+        ""\r\r
+    };\r\r
+    private static final String[] list40 = {\r\r
+        "ER", ""\r\r
+    };\r\r
+    private static final String[] list41 = {\r\r
+        "DANGER", "RANGER", "MANGER", ""\r\r
+    };\r\r
+    private static final String[] list42 = {\r\r
+        "E", "I", ""\r\r
+    };\r\r
+    private static final String[] list43 = {\r\r
+        "RGY", "OGY", ""\r\r
+    };\r\r
+    private static final String[] list44 = {\r\r
+        "E", "I", "Y", ""\r\r
+    };\r\r
+    private static final String[] list45 = {\r\r
+        "AGGI", "OGGI", ""\r\r
+    };\r\r
+    private static final String[] list46 = {\r\r
+        "VAN ", "VON ", ""\r\r
+    };\r\r
+    private static final String[] list47 = {\r\r
+        "SCH", ""\r\r
+    };\r\r
+    private static final String[] list48 = {\r\r
+        "ET", ""\r\r
+    };\r\r
+    private static final String[] list49 = {\r\r
+        "IER ", ""\r\r
+    };\r\r
+    private static final String[] list50 = {\r\r
+        "JOSE", ""\r\r
+    };\r\r
+    private static final String[] list51 = {\r\r
+        "SAN ", ""\r\r
+    };\r\r
+    private static final String[] list52 = {\r\r
+        "SAN ", ""\r\r
+    };\r\r
+    private static final String[] list53 = {\r\r
+        "JOSE", ""\r\r
+    };\r\r
+    private static final String[] list54 = {\r\r
+        "L", "T", "K", "S", "N", "M", "B", "Z", ""\r\r
+    };\r\r
+    private static final String[] list55 = {\r\r
+        "S", "K", "L", ""\r\r
+    };\r\r
+    private static final String[] list56 = {\r\r
+        "ILLO", "ILLA", "ALLE", ""\r\r
+    };\r\r
+    private static final String[] list57 = {\r\r
+        "AS", "OS", ""\r\r
+    };\r\r
+    private static final String[] list58 = {\r\r
+        "A", "O", ""\r\r
+    };\r\r
+    private static final String[] list59 = {\r\r
+        "ALLE", ""\r\r
+    };\r\r
+    private static final String[] list60 = {\r\r
+        "UMB", ""\r\r
+    };\r\r
+    private static final String[] list61 = {\r\r
+        "ER", ""\r\r
+    };\r\r
+    private static final String[] list62 = {\r\r
+        "P", "B", ""\r\r
+    };\r\r
+    private static final String[] list63 = {\r\r
+        "IE", ""\r\r
+    };\r\r
+    private static final String[] list64 = {\r\r
+        "ME", "MA", ""\r\r
+    };\r\r
+    private static final String[] list65 = {\r\r
+        "ISL", "YSL", ""\r\r
+    };\r\r
+    private static final String[] list66 = {\r\r
+        "SUGAR", ""\r\r
+    };\r\r
+    private static final String[] list67 = {\r\r
+        "SH", ""\r\r
+    };\r\r
+    private static final String[] list68 = {\r\r
+        "HEIM", "HOEK", "HOLM", "HOLZ", ""\r\r
+    };\r\r
+    private static final String[] list69 = {\r\r
+        "SIO", "SIA", ""\r\r
+    };\r\r
+    private static final String[] list70 = {\r\r
+        "SIAN", ""\r\r
+    };\r\r
+    private static final String[] list71 = {\r\r
+        "M", "N", "L", "W", ""\r\r
+    };\r\r
+    private static final String[] list72 = {\r\r
+        "Z", ""\r\r
+    };\r\r
+    private static final String[] list73 = {\r\r
+        "Z", ""\r\r
+    };\r\r
+    private static final String[] list74 = {\r\r
+        "SC", ""\r\r
+    };\r\r
+    private static final String[] list75 = {\r\r
+        "OO", "ER", "EN", "UY", "ED", "EM", ""\r\r
+    };\r\r
+    private static final String[] list76 = {\r\r
+        "ER", "EN", ""\r\r
+    };\r\r
+    private static final String[] list77 = {\r\r
+        "I", "E", "Y", ""\r\r
+    };\r\r
+    private static final String[] list78 = {\r\r
+        "AI", "OI", ""\r\r
+    };\r\r
+    private static final String[] list79 = {\r\r
+        "S", "Z", ""\r\r
+    };\r\r
+    private static final String[] list80 = {\r\r
+        "TION", ""\r\r
+    };\r\r
+    private static final String[] list81 = {\r\r
+        "TIA", "TCH", ""\r\r
+    };\r\r
+    private static final String[] list82 = {\r\r
+        "TH", ""\r\r
+    };\r\r
+    private static final String[] list83 = {\r\r
+        "TTH", ""\r\r
+    };\r\r
+    private static final String[] list84 = {\r\r
+        "OM", "AM", ""\r\r
+    };\r\r
+    private static final String[] list85 = {\r\r
+        "VAN ", "VON ", ""\r\r
+    };\r\r
+    private static final String[] list86 = {\r\r
+        "SCH", ""\r\r
+    };\r\r
+    private static final String[] list87 = {\r\r
+        "T", "D", ""\r\r
+    };\r\r
+    private static final String[] list88 = {\r\r
+        "WR", ""\r\r
+    };\r\r
+    private static final String[] list89 = {\r\r
+        "WH", ""\r\r
+    };\r\r
+    private static final String[] list90 = {\r\r
+        "EWSKI", "EWSKY", "OWSKI", "OWSKY", ""\r\r
+    };\r\r
+    private static final String[] list91 = {\r\r
+        "SCH", ""\r\r
+    };\r\r
+    private static final String[] list92 = {\r\r
+        "WICZ", "WITZ", ""\r\r
+    };\r\r
+    private static final String[] list93 = {\r\r
+        "IAU", "EAU", ""\r\r
+    };\r\r
+    private static final String[] list94 = {\r\r
+        "AU", "OU", ""\r\r
+    };\r\r
+    private static final String[] list95 = {\r\r
+        "C", "X", ""\r\r
+    };\r\r
+    private static final String[] list96 = {\r\r
+        "ZO", "ZI", "ZA", ""\r\r
+    };\r\r
+\r\r
+  /**\r\r
+   * put your documentation comment here\r\r
+   * @return\r\r
+   */\r\r
+  private final static boolean SlavoGermanic (String in) {\r\r
+    if ((in.indexOf("W") > -1) || (in.indexOf("K") > -1) || (in.indexOf("CZ") > -1)\r\r
+        || (in.indexOf("WITZ") > -1))\r\r
+      return  true;\r\r
+    return  false;\r\r
+  }\r\r
+\r\r
+  /**\r\r
+   * put your documentation comment here\r\r
+   * @param main\r\r
+   */\r\r
+  private final static void MetaphAdd (StringBuffer primary, String main) {\r\r
+    if (main != null) {\r\r
+      primary.append(main);\r\r
+    }\r\r
+  }\r\r
+\r\r
+  private final static void MetaphAdd (StringBuffer primary, char main) {\r\r
+    primary.append(main);\r\r
+  }  \r\r
\r\r
+  /**\r\r
+   * put your documentation comment here\r\r
+   * @param at\r\r
+   * @return\r\r
+   */\r\r
+  private final static boolean isVowel (String in, int at, int length) {\r\r
+    if ((at < 0) || (at >= length))\r\r
+      return  false;\r\r
+    char it = in.charAt(at);\r\r
+    if ((it == 'A') || (it == 'E') || (it == 'I') || (it == 'O') || (it ==\r\r
+        'U') || (it == 'Y'))\r\r
+      return  true;\r\r
+    return  false;\r\r
+  }\r\r
+\r\r
+  /**\r\r
+   * put your documentation comment here\r\r
+   * @param string\r\r
+   * @param start\r\r
+   * @param length\r\r
+   * @param list\r\r
+   * @return\r\r
+   */\r\r
+  private final static boolean stringAt (String string, int start, int length, String[] list) {\r\r
+    if ((start < 0) || (start >= string.length()) || list.length == 0 )\r\r
+      return  false;\r\r
+    String substr = string.substring(start, start + length);\r\r
+    for (int i = 0; i < list.length; i++) {\r\r
+      if (list[i].equals(substr))\r\r
+        return  true;\r\r
+    }\r\r
+    return  false;\r\r
+  }\r\r
+\r\r
+  /**\r\r
+   * put your documentation comment here\r\r
+   * @param word The word to process.\r\r
+   * @return\r\r
+   */\r\r
+  public final String transform (String word) {\r\r
+    StringBuffer primary = new StringBuffer( word.length() + 5 );\r\r
+    String in = word.toUpperCase() + "     ";\r\r
+    int current = 0;\r\r
+    int length = in.length();\r\r
+    if (length < 1)\r\r
+      return  "";\r\r
+    int last = length - 1;\r\r
+    boolean isSlavoGermaic = SlavoGermanic(in);\r\r
+    if (stringAt(in, 0, 2, myList))\r\r
+      current += 1;\r\r
+    if (in.charAt(0) == 'X') {\r\r
+      MetaphAdd(primary, 'S');\r\r
+      current += 1;\r\r
+    }\r\r
+    while (current < length ) {\r\r
+      switch (in.charAt(current)) {\r\r
+        case 'A':case 'E':case 'I':case 'O':case 'U':case 'Y':\r\r
+          if (current == 0)\r\r
+            MetaphAdd(primary, 'A');\r\r
+          current += 1;\r\r
+          break;\r\r
+        case 'B':\r\r
+          MetaphAdd(primary, 'P');\r\r
+          if (in.charAt(current + 1) == 'B')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'Ç':\r\r
+          MetaphAdd(primary, 'S');\r\r
+          current += 1;\r\r
+          break;\r\r
+        case 'C':\r\r
+          if ((current > 1) && !isVowel(in, current - 2, length) && stringAt(in, (current\r\r
+              - 1), 3, list1) && (in.charAt(current + 2) != 'I') && (in.charAt(\r\r
+              current + 2) != 'E') || stringAt(in, (current - 2), 6, list2)) {\r\r
+            MetaphAdd(primary, 'K');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == 0) && stringAt(in, current, 6, list3)) {\r\r
+            MetaphAdd(primary, 'S');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 4, list4)) {\r\r
+            MetaphAdd(primary, 'K');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list5)) {\r\r
+            if ((current > 0) && stringAt(in, current, 4, list6)) {\r\r
+              MetaphAdd(primary, 'K' );\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+            if ((current == 0) && stringAt(in, (current + 1), 5, list7) ||\r\r
+                stringAt(in, current + 1, 3, list8) && !stringAt(in, 0, 5,\r\r
+                list9)) {\r\r
+              MetaphAdd(primary, 'K' );\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+            if (stringAt(in, 0, 4, list10) || stringAt(in, 0, 3, list11) ||\r\r
+                stringAt(in, current - 2, 6, list12) || stringAt(in, current\r\r
+                + 2, 1, list13) || (stringAt(in, current - 1, 1, list14) ||\r\r
+                (current == 0)) && stringAt(in, current + 2, 1, list15)) {\r\r
+              MetaphAdd(primary, 'K');\r\r
+            }\r\r
+            else {\r\r
+              if (current > 0) {\r\r
+                if (stringAt(in, 0, 2, list16))\r\r
+                  MetaphAdd(primary, 'K');\r\r
+                else\r\r
+                  MetaphAdd(primary, 'X');\r\r
+              }\r\r
+              else {\r\r
+                MetaphAdd(primary, 'X');\r\r
+              }\r\r
+            }\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list17) && !stringAt(in, current, 4,\r\r
+              list18)) {\r\r
+            MetaphAdd(primary, 'S');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list19)) {\r\r
+            MetaphAdd(primary, 'X');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list20) && !((current == 1) && in.charAt(0)\r\r
+              == 'M')) {\r\r
+            if (stringAt(in, current + 2, 1, list21) && !stringAt(in, current\r\r
+                + 2, 2, list22)) {\r\r
+              if (((current == 1) && (in.charAt(current - 1) == 'A')) || stringAt(in,\r\r
+                  (current - 1), 5, list23))\r\r
+                MetaphAdd(primary, "KS");\r\r
+              else\r\r
+                MetaphAdd(primary, 'X');\r\r
+              current += 3;\r\r
+              break;\r\r
+            }\r\r
+            else {\r\r
+              MetaphAdd(primary, 'K');\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list24)) {\r\r
+            MetaphAdd(primary, 'K');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          else if (stringAt(in, current, 2, list25)) {\r\r
+            MetaphAdd(primary, 'S');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          \r\r
+          MetaphAdd(primary, 'K');\r\r
+          if (stringAt(in, current + 1, 2, list27))\r\r
+            current += 3;\r\r
+          else if (stringAt(in, current + 1, 1, list28) && !stringAt(in, current\r\r
+              + 1, 2, list29))\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'D':\r\r
+          if (stringAt(in, current, 2, list30)) {\r\r
+            if (stringAt(in, current + 2, 1, list31)) {\r\r
+              MetaphAdd(primary, 'J');\r\r
+              current += 3;\r\r
+              break;\r\r
+            }\r\r
+            else {\r\r
+              MetaphAdd(primary, "TK");\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+          }\r\r
+          MetaphAdd(primary, 'T');\r\r
+          if (stringAt(in, current, 2, list32)) {\r\r
+            current += 2;\r\r
+          } else {\r\r
+            current += 1;\r\r
+          }\r\r
+          break;\r\r
+        case 'F':\r\r
+          if (in.charAt(current + 1) == 'F')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'F');\r\r
+          break;\r\r
+        case 'G':\r\r
+          if (in.charAt(current + 1) == 'H') {\r\r
+            if ((current > 0) && !isVowel(in, current - 1, length)) {\r\r
+              MetaphAdd(primary, 'K');\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+            if (current < 3) {\r\r
+              if (current == 0) {\r\r
+                if (in.charAt(current + 2) == 'I')\r\r
+                  MetaphAdd(primary, 'J');\r\r
+                else\r\r
+                  MetaphAdd(primary, 'K');\r\r
+                current += 2;\r\r
+                break;\r\r
+              }\r\r
+            }\r\r
+            if ((current > 1) && stringAt(in, current - 2, 1, list33) || ((current > 2)\r\r
+                && stringAt(in, current - 3, 1, list34)) || ((current > 3) &&\r\r
+                stringAt(in, current - 4, 1, list35))) {\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+            else {\r\r
+              if ((current > 2) && (in.charAt(current - 1) == 'U') && stringAt(in,\r\r
+                  current - 3, 1, list36)) {\r\r
+                MetaphAdd(primary, 'F');\r\r
+              }\r\r
+              else {\r\r
+                if ((current > 0) && (in.charAt(current - 1) != 'I'))\r\r
+                  MetaphAdd(primary, 'K');\r\r
+              }\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+          }\r\r
+          if (in.charAt(current + 1) == 'N') {\r\r
+            if ((current == 1) && isVowel(in, 0, length) && !isSlavoGermaic) {\r\r
+              MetaphAdd(primary, "KN");\r\r
+            }\r\r
+            else {\r\r
+              if (!stringAt(in, current + 2, 2, list37) && (in.charAt(current\r\r
+                  + 1) != 'Y') && !isSlavoGermaic) {\r\r
+                MetaphAdd(primary, "N");\r\r
+              }\r\r
+              else {\r\r
+                MetaphAdd(primary, "KN");\r\r
+              }\r\r
+            }\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current + 1, 2, list38) && !isSlavoGermaic) {\r\r
+            MetaphAdd(primary, "KL");\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == 0) && ((in.charAt(current + 1) == 'Y') || stringAt(in,\r\r
+              current + 1, 2, list39))) {\r\r
+            MetaphAdd(primary, 'K');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if ((stringAt(in, current + 1, 2, list40) || (in.charAt(current +\r\r
+              1) == 'Y')) && !stringAt(in, 0, 6, list41) && !stringAt(in, current\r\r
+              - 1, 1, list42) && !stringAt(in, current - 1, 3, list43)) {\r\r
+            MetaphAdd(primary, 'K');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current + 1, 1, list44) || stringAt(in, current -\r\r
+              1, 4, list45)) {\r\r
+            if (stringAt(in, 0, 4, list46) || stringAt(in, 0, 3, list47) ||\r\r
+                stringAt(in, current + 1, 2, list48)) {\r\r
+              MetaphAdd(primary, 'K');\r\r
+            }\r\r
+            else {\r\r
+                MetaphAdd(primary, 'J');\r\r
+            }\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (in.charAt(current + 1) == 'G')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'K');\r\r
+          break;\r\r
+        case 'H':\r\r
+          if (((current == 0) || isVowel(in, current - 1, length)) && isVowel(in, current +\r\r
+              1, length)) {\r\r
+            MetaphAdd(primary, 'H');\r\r
+            current += 2;\r\r
+          }\r\r
+          else {\r\r
+            current += 1;\r\r
+          }\r\r
+          break;\r\r
+        case 'J':\r\r
+          if (stringAt(in, current, 4, list50) || stringAt(in, 0, 4, list51)) {\r\r
+            if ((current == 0) && (in.charAt(current + 4) == ' ') || stringAt(in,\r\r
+                0, 4, list52)) {\r\r
+              MetaphAdd(primary, 'H');\r\r
+            }\r\r
+            else {\r\r
+              MetaphAdd(primary, 'J');\r\r
+            }\r\r
+            current += 1;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == 0) && !stringAt(in, current, 4, list53)) {\r\r
+            MetaphAdd(primary, 'J');\r\r
+          }\r\r
+          else {\r\r
+            if (isVowel(in, current - 1, length) && !isSlavoGermaic && ((in.charAt(current\r\r
+                + 1) == 'A') || in.charAt(current + 1) == 'O')) {\r\r
+              MetaphAdd(primary, 'J' );\r\r
+            }\r\r
+            else {\r\r
+              if (current == last) {\r\r
+                MetaphAdd(primary, 'J' );\r\r
+              }\r\r
+              else {\r\r
+                if (!stringAt(in, current + 1, 1, list54) && !stringAt(in,\r\r
+                    current - 1, 1, list55)) {\r\r
+                  MetaphAdd(primary, 'J');\r\r
+                }\r\r
+              }\r\r
+            }\r\r
+          }\r\r
+          if (in.charAt(current + 1) == 'J')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'K':\r\r
+          if (in.charAt(current + 1) == 'K')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'K');\r\r
+          break;\r\r
+        case 'L':\r\r
+          if (in.charAt(current + 1) == 'L') {\r\r
+            if (((current == (length - 3)) && stringAt(in, current - 1, 4,\r\r
+                list56)) || ((stringAt(in, last - 1, 2, list57) || stringAt(in,\r\r
+                last, 1, list58)) && stringAt(in, current - 1, 4, list59))) {\r\r
+              MetaphAdd(primary, 'L' );\r\r
+              current += 2;\r\r
+              break;\r\r
+            }\r\r
+            current += 2;\r\r
+          }\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'L');\r\r
+          break;\r\r
+        case 'M':\r\r
+          if ((stringAt(in, current - 1, 3, list60) && (((current + 1) == last)\r\r
+              || stringAt(in, current + 2, 2, list61))) || (in.charAt(current\r\r
+              + 1) == 'M'))\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'M');\r\r
+          break;\r\r
+        case 'N':\r\r
+          if (in.charAt(current + 1) == 'N')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'N');\r\r
+          break;\r\r
+        case 'Ñ':\r\r
+          current += 1;\r\r
+          MetaphAdd(primary, 'N');\r\r
+          break;\r\r
+        case 'P':\r\r
+          if (in.charAt(current + 1) == 'N') {\r\r
+            MetaphAdd(primary, 'F');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current + 1, 1, list62))\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'P');\r\r
+          break;\r\r
+        case 'Q':\r\r
+          if (in.charAt(current + 1) == 'Q')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'K');\r\r
+          break;\r\r
+        case 'R':\r\r
+          if ((current == last) && !isSlavoGermaic && stringAt(in, current\r\r
+              - 2, 2, list63) && !stringAt(in, current - 4, 2, list64)) {\r\r
+//            MetaphAdd(primary, "");\r\r
+          } else\r\r
+            MetaphAdd(primary, 'R');\r\r
+          if (in.charAt(current + 1) == 'R')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'S':\r\r
+          if (stringAt(in, current - 1, 3, list65)) {\r\r
+            current += 1;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == 0) && stringAt(in, current, 5, list66)) {\r\r
+            MetaphAdd(primary, 'X');\r\r
+            current += 1;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list67)) {\r\r
+            if (stringAt(in, current + 1, 4, list68))\r\r
+              MetaphAdd(primary, 'S');\r\r
+            else\r\r
+              MetaphAdd(primary, 'X');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 3, list69) || stringAt(in, current, 4,\r\r
+              list70)) {\r\r
+            MetaphAdd(primary, 'S');\r\r
+            current += 3;\r\r
+            break;\r\r
+          }\r\r
+          if (((current == 0) && stringAt(in, current + 1, 1, list71)) || stringAt(in,\r\r
+              current + 1, 1, list72)) {\r\r
+            MetaphAdd(primary, 'S');\r\r
+            if (stringAt(in, current + 1, 1, list73))\r\r
+              current += 2;\r\r
+            else\r\r
+              current += 1;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list74)) {\r\r
+            if (in.charAt(current + 2) == 'H')\r\r
+              if (stringAt(in, current + 3, 2, list75)) {\r\r
+                if (stringAt(in, current + 3, 2, list76)) {\r\r
+                  MetaphAdd(primary, "X");\r\r
+                }\r\r
+                else {\r\r
+                  MetaphAdd(primary, "SK");\r\r
+                }\r\r
+                current += 3;\r\r
+                break;\r\r
+              }\r\r
+              else {\r\r
+                MetaphAdd(primary, 'X');\r\r
+                current += 3;\r\r
+                break;\r\r
+              }\r\r
+            if (stringAt(in, current + 2, 1, list77)) {\r\r
+              MetaphAdd(primary, 'S');\r\r
+              current += 3;\r\r
+              break;\r\r
+            }\r\r
+            MetaphAdd(primary, "SK");\r\r
+            current += 3;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == last) && stringAt(in, current - 2, 2, list78)) {\r\r
+            //MetaphAdd(primary, "");\r\r
+          } else\r\r
+            MetaphAdd(primary, 'S');\r\r
+          if (stringAt(in, current + 1, 1, list79))\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'T':\r\r
+          if (stringAt(in, current, 4, list80)) {\r\r
+            MetaphAdd(primary, 'X');\r\r
+            current += 3;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 3, list81)) {\r\r
+            MetaphAdd(primary, 'X');\r\r
+            current += 3;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 2, list82) || stringAt(in, current, 3,\r\r
+              list83)) {\r\r
+            if (stringAt(in, (current + 2), 2, list84) || stringAt(in, 0, 4,\r\r
+                list85) || stringAt(in, 0, 3, list86)) {\r\r
+              MetaphAdd(primary, 'T');\r\r
+            }\r\r
+            else {\r\r
+              MetaphAdd(primary, '0');\r\r
+            }\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current + 1, 1, list87)) {\r\r
+            current += 2;\r\r
+          }\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'T');\r\r
+          break;\r\r
+        case 'V':\r\r
+          if (in.charAt(current + 1) == 'V')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          MetaphAdd(primary, 'F');\r\r
+          break;\r\r
+        case 'W':\r\r
+          if (stringAt(in, current, 2, list88)) {\r\r
+            MetaphAdd(primary, 'R');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }\r\r
+          if ((current == 0) && (isVowel(in, current + 1, length) || stringAt(in, current,\r\r
+              2, list89))) {\r\r
+            MetaphAdd(primary, 'A');\r\r
+          }\r\r
+          if (((current == last) && isVowel(in, current - 1, length)) || stringAt(in, current\r\r
+              - 1, 5, list90) || stringAt(in, 0, 3, list91)) {\r\r
+            MetaphAdd(primary, 'F');\r\r
+            current += 1;\r\r
+            break;\r\r
+          }\r\r
+          if (stringAt(in, current, 4, list92)) {\r\r
+            MetaphAdd(primary, "TS");\r\r
+            current += 4;\r\r
+            break;\r\r
+          }\r\r
+          current += 1;\r\r
+          break;\r\r
+        case 'X':\r\r
+          if (!((current == last) && (stringAt(in, current - 3, 3, list93) ||\r\r
+              stringAt(in, current - 2, 2, list94))))\r\r
+            MetaphAdd(primary, "KS");\r\r
+          if (stringAt(in, current + 1, 1, list95))\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        case 'Z':\r\r
+          if (in.charAt(current + 1) == 'H') {\r\r
+            MetaphAdd(primary, 'J');\r\r
+            current += 2;\r\r
+            break;\r\r
+          }            \r\r
+          else {\r\r
+            MetaphAdd(primary, 'S');\r\r
+          }\r\r
+          if (in.charAt(current + 1) == 'Z')\r\r
+            current += 2;\r\r
+          else\r\r
+            current += 1;\r\r
+          break;\r\r
+        default:\r\r
+          current += 1;\r\r
+      }\r\r
+    }\r\r
+    return  primary.toString();\r\r
+  }\r\r
+}\r\r
+\r\r
+\r\r
+\r\r