Bug 1022262 - Part 2: Update Hunspell to version 1.3.3. r=ehsan
authorRyan VanderMeulen <ryanvm@gmail.com>
Tue, 17 Jun 2014 15:54:39 -0400
changeset 189165 9dd214468019302495a6ade1f275046444295c1a
parent 189164 6e7a401f824b33a639d4bccf3c0028f7c854615c
child 189166 383ee3bc79a66957f0ae3266de33a59a8152f213
push idunknown
push userunknown
push dateunknown
reviewersehsan
bugs1022262
milestone33.0a1
Bug 1022262 - Part 2: Update Hunspell to version 1.3.3. r=ehsan
extensions/spellcheck/hunspell/src/README
extensions/spellcheck/hunspell/src/README.mozilla
extensions/spellcheck/hunspell/src/affentry.cxx
extensions/spellcheck/hunspell/src/affentry.hxx
extensions/spellcheck/hunspell/src/affixmgr.cxx
extensions/spellcheck/hunspell/src/affixmgr.hxx
extensions/spellcheck/hunspell/src/atypes.hxx
extensions/spellcheck/hunspell/src/baseaffix.hxx
extensions/spellcheck/hunspell/src/csutil.cxx
extensions/spellcheck/hunspell/src/csutil.hxx
extensions/spellcheck/hunspell/src/dictmgr.cxx
extensions/spellcheck/hunspell/src/dictmgr.hxx
extensions/spellcheck/hunspell/src/filemgr.cxx
extensions/spellcheck/hunspell/src/filemgr.hxx
extensions/spellcheck/hunspell/src/hashmgr.cxx
extensions/spellcheck/hunspell/src/hashmgr.hxx
extensions/spellcheck/hunspell/src/htypes.hxx
extensions/spellcheck/hunspell/src/hunspell.cxx
extensions/spellcheck/hunspell/src/hunspell.h
extensions/spellcheck/hunspell/src/hunspell.hxx
extensions/spellcheck/hunspell/src/hunvisapi.h
extensions/spellcheck/hunspell/src/hunzip.cxx
extensions/spellcheck/hunspell/src/hunzip.hxx
extensions/spellcheck/hunspell/src/langnum.hxx
extensions/spellcheck/hunspell/src/license.hunspell
extensions/spellcheck/hunspell/src/patches/01-675553.diff
extensions/spellcheck/hunspell/src/patches/02-690892.diff
extensions/spellcheck/hunspell/src/patches/03-clang.diff
extensions/spellcheck/hunspell/src/patches/04-777292.diff
extensions/spellcheck/hunspell/src/patches/05-579517.diff
extensions/spellcheck/hunspell/src/patches/06-784776.diff
extensions/spellcheck/hunspell/src/patches/07-927728.diff
extensions/spellcheck/hunspell/src/patches/08-943268.diff
extensions/spellcheck/hunspell/src/patches/09-license.diff
extensions/spellcheck/hunspell/src/phonet.cxx
extensions/spellcheck/hunspell/src/phonet.hxx
extensions/spellcheck/hunspell/src/replist.cxx
extensions/spellcheck/hunspell/src/replist.hxx
extensions/spellcheck/hunspell/src/suggestmgr.cxx
extensions/spellcheck/hunspell/src/suggestmgr.hxx
extensions/spellcheck/hunspell/src/w_char.hxx
new file mode 100644
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/README
@@ -0,0 +1,182 @@
+About Hunspell
+--------------
+
+Hunspell is a spell checker and morphological analyzer library and program
+designed for languages with rich morphology and complex word compounding or
+character encoding. Hunspell interfaces: Ispell-like terminal interface
+using Curses library, Ispell pipe interface, OpenOffice.org UNO module.
+
+Hunspell's code base comes from the OpenOffice.org MySpell
+(http://lingucomponent.openoffice.org/MySpell-3.zip). See README.MYSPELL,
+AUTHORS.MYSPELL and license.myspell files.
+Hunspell is designed to eventually replace Myspell in OpenOffice.org.
+
+Main features of Hunspell spell checker and morphological analyzer:
+
+- Unicode support (affix rules work only with the first 65535 Unicode characters)
+
+- Morphological analysis (in custom item and arrangement style) and stemming
+
+- Max. 65535 affix classes and twofold affix stripping (for agglutinative
+  languages, like Azeri, Basque, Estonian, Finnish, Hungarian, Turkish, etc.)
+
+- Support complex compoundings (for example, Hungarian and German)
+
+- Support language specific features (for example, special casing of
+  Azeri and Turkish dotted i, or German sharp s)
+
+- Handle conditional affixes, circumfixes, fogemorphemes,
+  forbidden words, pseudoroots and homonyms.
+
+- Free software (LGPL, GPL, MPL tri-license)
+
+Compiling on Unix/Linux
+-----------------------
+
+./configure
+make
+make install
+
+For dictionary development, use the --with-warnings option of configure.
+
+For interactive user interface of Hunspell executable, use the --with-ui option.
+
+The developer packages you need to compile Hunspell's interface:
+
+glibc-devel
+
+optional developer packages:
+
+ncurses (need for --with-ui), eg. libncursesw5 for UTF-8
+readline (for fancy input line editing,
+  configure parameter: --with-readline)
+locale and gettext (but you can also use the
+  --with-included-gettext configure parameter)
+
+Hunspell distribution uses new Autoconf (2.59) and Automake (1.9).
+
+Compiling on Windows
+--------------------
+
+1. Compiling with Windows SDK
+
+Download the free Windows SDK of Microsoft, open a command prompt
+window and cd into hunspell/src/win_api. Use the following command
+to compile hunspell:
+
+vcbuild
+
+2. Compiling in Cygwin environment
+
+Download and install Cygwin environment for Windows with the following
+extra packages: 
+
+make
+gcc-g++ development package
+mingw development package (for cygwin.dll free native Windows compilation)
+ncurses, readline (for user interface)
+iconv (character conversion)
+
+2.1. Cygwin1.dll dependent compiling
+
+Open a Cygwin shell, cd into the hunspell root directory:
+
+./configure
+make
+make install
+
+For dictionary development, use the --with-warnings option of configure.
+
+For interactive user interface of Hunspell executable, use the --with-ui option.
+
+readline configure parameter: --with-readline (for fancy input line editing)
+
+1.2. Cygwin1.dll free compiling
+
+Open a Cygwin shell, cd into the hunspell/src/win_api and
+
+make -f Makefile.cygwin
+
+Testing
+-------
+
+Testing Hunspell (see tests in tests/ subdirectory):
+
+make check
+
+or with Valgrind debugger:
+
+make check
+VALGRIND=[Valgrind_tool] make check
+
+For example:
+
+make check
+VALGRIND=memcheck make check
+
+Documentation
+-------------
+
+features and dictionary format:
+man 5 hunspell
+
+man hunspell
+hunspell -h
+http://hunspell.sourceforge.net
+
+Usage
+-----
+
+The src/tools dictionary contains ten executables after compiling
+(or some of them are in the src/win_api):
+
+affixcompress: dictionary generation from large (millions of words) vocabularies
+  analyze: example of spell checking, stemming and morphological analysis
+  chmorph: example of automatic morphological generation and conversion
+  example: example of spell checking and suggestion
+ hunspell: main program for spell checking and others (see manual)
+   hunzip: decompressor of hzip format
+     hzip: compressor of hzip format
+makealias: alias compression (Hunspell only, not back compatible with MySpell)
+    munch: dictionary generation from vocabularies (it needs an affix file, too).
+  unmunch: list all recognized words of a MySpell dictionary
+wordforms: word generation (Hunspell version of unmunch)
+
+After compiling and installing (see INSTALL) you can
+run the Hunspell spell checker (compiled with user interface)
+with a Hunspell or Myspell dictionary:
+
+hunspell -d en_US text.txt
+
+or without interface:
+
+hunspell
+hunspell -d en_UK -l <text.txt
+
+Dictionaries consist of an affix and dictionary file, see tests/
+or http://wiki.services.openoffice.org/wiki/Dictionaries.
+
+Using Hunspell library with GCC
+-------------------------------
+
+Including in your program:
+#include <hunspell.hxx>
+
+Linking with Hunspell static library:
+g++ -lhunspell example.cxx 
+
+Dictionaries
+------------
+
+Myspell & Hunspell dictionaries:
+http://extensions.libreoffice.org
+http://cgit.freedesktop.org/libreoffice/dictionaries
+http://extensions.openoffice.org
+http://wiki.services.openoffice.org/wiki/Dictionaries
+
+Aspell dictionaries (need some conversion):
+ftp://ftp.gnu.org/gnu/aspell/dict
+Conversion steps: see relevant feature request at http://hunspell.sf.net.
+
+László Németh
+nemeth at numbertext org
--- a/extensions/spellcheck/hunspell/src/README.mozilla
+++ b/extensions/spellcheck/hunspell/src/README.mozilla
@@ -1,61 +1,2 @@
-******* BEGIN LICENSE BLOCK *******
-* Version: MPL 1.1/GPL 2.0/LGPL 2.1
-* 
-* The contents of this file are subject to the Mozilla Public License Version
-* 1.1 (the "License"); you may not use this file except in compliance with
-* the License. You may obtain a copy of the License at
-* http://www.mozilla.org/MPL/
-* 
-* Software distributed under the License is distributed on an "AS IS" basis,
-* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-* for the specific language governing rights and limitations under the
-* License.
-* 
-* The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
-* and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
-* are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
-* 
-* Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
-*                 David Einstein (deinst@world.std.com)
-*                 Lszl Nmeth (nemethl@gyorsposta.hu)
-*                 Ryan VanderMeulen (ryanvm@gmail.com)
-*                 Caolan McNamara (caolanm@redhat.com)
-* 
-* Alternatively, the contents of this file may be used under the terms of
-* either the GNU General Public License Version 2 or later (the "GPL"), or
-* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
-* in which case the provisions of the GPL or the LGPL are applicable instead
-* of those above. If you wish to allow use of your version of this file only
-* under the terms of either the GPL or the LGPL, and not to allow others to
-* use your version of this file under the terms of the MPL, indicate your
-* decision by deleting the provisions above and replace them with the notice
-* and other provisions required by the GPL or the LGPL. If you do not delete
-* the provisions above, a recipient may use your version of this file under
-* the terms of any one of the MPL, the GPL or the LGPL.
-*
-******* END LICENSE BLOCK *******
-
-Hunspell Version:   1.3.2
-Additional Patches: 694002, 710967, 710940, 784776
-
-Hunspell Author: Lszl Nmeth
-MySpell Author: Kevin Hendricks & David Einstein
-
-Hunspell is a spell checker and morphological analyser library. Hunspell
-is based on OpenOffice.org's Myspell. Documentation, tests, and examples
-are available at http://hunspell.sourceforge.net.
-
-A special thanks and credit goes to Geoff Kuenning, the creator of Ispell.
-MySpell's affix algorithms were based on those of Ispell, which should be
-noted is copyright Geoff Kuenning et al and now available under a BSD-style
-license. For more information on Ispell and affix compression in general,
-please see: http://lasr.cs.ucla.edu/geoff/ispell.html (Ispell homepage)
-
-An almost complete rewrite of MySpell for use by the Mozilla project was
-developed by David Einstein. David was a significant help in improving MySpell.
-
-Special thanks also goes to Lszl Nmeth, who is the author of the Hungarian
-dictionary and who developed and contributed the code to support compound words
-in MySpell and fixed numerous problems with the encoding case conversion tables
-along with rewriting MySpell as Hunspell and ensuring compatibility with the
-Mozilla codebase.
+Hunspell Version:   1.3.3
+Additional Patches: See patches directory.
--- a/extensions/spellcheck/hunspell/src/affentry.cxx
+++ b/extensions/spellcheck/hunspell/src/affentry.cxx
@@ -1,95 +1,42 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 
 #include "affentry.hxx"
 #include "csutil.hxx"
 
+#define MAXTEMPWORDLEN (MAXWORDUTF8LEN + 4)
+
 PfxEntry::PfxEntry(AffixMgr* pmgr, affentry* dp)
+    // register affix manager
+    : pmyMgr(pmgr)
+    , next(NULL)
+    , nexteq(NULL)
+    , nextne(NULL)
+    , flgnxt(NULL)
 {
-  // register affix manager
-  pmyMgr = pmgr;
-
   // set up its initial values
-
   aflag = dp->aflag;         // flag
   strip = dp->strip;         // string to strip
   appnd = dp->appnd;         // string to append
   stripl = dp->stripl;       // length of strip string
   appndl = dp->appndl;       // length of append string
   numconds = dp->numconds;   // length of the condition
   opts = dp->opts;           // cross product flag
   // then copy over all of the conditions
   if (opts & aeLONGCOND) {
     memcpy(c.conds, dp->c.l.conds1, MAXCONDLEN_1);
     c.l.conds2 = dp->c.l.conds2;
   } else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
-  next = NULL;
-  nextne = NULL;
-  nexteq = NULL;
   morphcode = dp->morphcode;
   contclass = dp->contclass;
   contclasslen = dp->contclasslen;
 }
 
 
 PfxEntry::~PfxEntry()
 {
@@ -102,26 +49,27 @@ PfxEntry::~PfxEntry()
     if (opts & aeLONGCOND) free(c.l.conds2);
     if (morphcode && !(opts & aeALIASM)) free(morphcode);
     if (contclass && !(opts & aeALIASF)) free(contclass);
 }
 
 // add prefix to this word assuming conditions hold
 char * PfxEntry::add(const char * word, int len)
 {
-    char tword[MAXWORDUTF8LEN + 4];
+    char tword[MAXTEMPWORDLEN];
 
     if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) && 
        (len >= numconds) && test_condition(word) &&
        (!stripl || (strncmp(word, strip, stripl) == 0)) &&
-       ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
+       ((MAXTEMPWORDLEN) > (len + appndl - stripl))) {
     /* we have a match so add prefix */
               char * pp = tword;
               if (appndl) {
-                  strcpy(tword,appnd);
+                  strncpy(tword, appnd, MAXTEMPWORDLEN-1);
+                  tword[MAXTEMPWORDLEN-1] = '\0';
                   pp += appndl;
                }
                strcpy(pp, (word + stripl));
                return mystrdup(tword);
      }
      return NULL;
 }
 
@@ -159,74 +107,79 @@ inline int PfxEntry::test_condition(cons
                 if ((neg && ingroup) || (!neg && !ingroup)) return 0;
                 pos = NULL;
                 p = nextchar(p);
                 // skip the next character
                 if (!ingroup && *st) for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++);
                 if (*st == '\0' && p) return 0; // word <= condition
                 break;
             }
-         case '.': if (!pos) { // dots are not metacharacters in groups: [.]
+         case '.':
+            if (!pos) { // dots are not metacharacters in groups: [.]
                 p = nextchar(p);
                 // skip the next character
                 for (st++; (opts & aeUTF8) && (*st & 0xc0) == 0x80; st++);
                 if (*st == '\0' && p) return 0; // word <= condition
                 break;
             }
+            /* FALLTHROUGH */
     default: {
                 if (*st == *p) {
                     st++;
                     p = nextchar(p);
                     if ((opts & aeUTF8) && (*(st - 1) & 0x80)) { // multibyte
                         while (p && (*p & 0xc0) == 0x80) {       // character
                             if (*p != *st) {
                                 if (!pos) return 0;
                                 st = pos;
                                 break;
                             }
                             p = nextchar(p);
                             st++;
                         }
                         if (pos && st != pos) {
                             ingroup = true;
-                            while (p && *p != ']' && (p = nextchar(p)));
+                            while (p && *p != ']' && ((p = nextchar(p)) != NULL));
                         }
                     } else if (pos) {
                         ingroup = true;
-                        while (p && *p != ']' && (p = nextchar(p)));
+                        while (p && *p != ']' && ((p = nextchar(p)) != NULL));
                     }
                 } else if (pos) { // group
                     p = nextchar(p);
                 } else return 0;
             }
       }
       if (!p) return 1;
     }
 }
 
 // check if this prefix entry matches
 struct hentry * PfxEntry::checkword(const char * word, int len, char in_compound, const FLAG needflag)
 {
     int                 tmpl;   // length of tmpword
     struct hentry *     he;     // hash entry of root word or NULL
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
 
     // on entry prefix is 0 length or already matches the beginning of the word.
     // So if the remaining root word has positive length
     // and if there are enough chars in root word and added back strip chars
     // to meet the number of characters conditions, then test it
 
      tmpl = len - appndl;
 
      if (tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) {
 
             // generate new root word by removing prefix and adding
             // back any characters that would have been stripped
 
-            if (stripl) strcpy (tmpword, strip);
+            if (stripl) {
+                strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+                tmpword[MAXTEMPWORDLEN-1] = '\0';
+            }
             strcpy ((tmpword + stripl), (word + appndl));
 
             // now make sure all of the conditions on characters
             // are met.  Please see the appendix at the end of
             // this file for more info on exactly what is being
             // tested
 
             // if all conditions are met then check if resulting
@@ -263,32 +216,35 @@ struct hentry * PfxEntry::checkword(cons
 }
 
 // check if this prefix entry matches
 struct hentry * PfxEntry::check_twosfx(const char * word, int len,
     char in_compound, const FLAG needflag)
 {
     int                 tmpl;   // length of tmpword
     struct hentry *     he;     // hash entry of root word or NULL
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
 
     // on entry prefix is 0 length or already matches the beginning of the word.
     // So if the remaining root word has positive length
     // and if there are enough chars in root word and added back strip chars
     // to meet the number of characters conditions, then test it
 
      tmpl = len - appndl;
 
      if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
         (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing prefix and adding
             // back any characters that would have been stripped
 
-            if (stripl) strcpy (tmpword, strip);
+            if (stripl) {
+                strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+                tmpword[MAXTEMPWORDLEN-1] = '\0';
+            }
             strcpy ((tmpword + stripl), (word + appndl));
 
             // now make sure all of the conditions on characters
             // are met.  Please see the appendix at the end of
             // this file for more info on exactly what is being
             // tested
 
             // if all conditions are met then check if resulting
@@ -310,32 +266,35 @@ struct hentry * PfxEntry::check_twosfx(c
     return NULL;
 }
 
 // check if this prefix entry matches
 char * PfxEntry::check_twosfx_morph(const char * word, int len,
          char in_compound, const FLAG needflag)
 {
     int                 tmpl;   // length of tmpword
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
 
     // on entry prefix is 0 length or already matches the beginning of the word.
     // So if the remaining root word has positive length
     // and if there are enough chars in root word and added back strip chars
     // to meet the number of characters conditions, then test it
 
      tmpl = len - appndl;
 
      if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
         (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing prefix and adding
             // back any characters that would have been stripped
 
-            if (stripl) strcpy (tmpword, strip);
+            if (stripl) {
+                strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+                tmpword[MAXTEMPWORDLEN-1] = '\0';
+            }
             strcpy ((tmpword + stripl), (word + appndl));
 
             // now make sure all of the conditions on characters
             // are met.  Please see the appendix at the end of
             // this file for more info on exactly what is being
             // tested
 
             // if all conditions are met then check if resulting
@@ -357,17 +316,17 @@ char * PfxEntry::check_twosfx_morph(cons
     return NULL;
 }
 
 // check if this prefix entry matches
 char * PfxEntry::check_morph(const char * word, int len, char in_compound, const FLAG needflag)
 {
     int                 tmpl;   // length of tmpword
     struct hentry *     he;     // hash entry of root word or NULL
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
     char                result[MAXLNLEN];
     char * st;
 
     *result = '\0';
 
     // on entry prefix is 0 length or already matches the beginning of the word.
     // So if the remaining root word has positive length
     // and if there are enough chars in root word and added back strip chars
@@ -376,17 +335,20 @@ char * PfxEntry::check_morph(const char 
      tmpl = len - appndl;
 
      if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
         (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing prefix and adding
             // back any characters that would have been stripped
 
-            if (stripl) strcpy (tmpword, strip);
+            if (stripl) {
+                strncpy(tmpword, strip, MAXTEMPWORDLEN-1);
+                tmpword[MAXTEMPWORDLEN-1] = '\0';
+            }
             strcpy ((tmpword + stripl), (word + appndl));
 
             // now make sure all of the conditions on characters
             // are met.  Please see the appendix at the end of
             // this file for more info on exactly what is being
             // tested
 
             // if all conditions are met then check if resulting
@@ -444,37 +406,39 @@ char * PfxEntry::check_morph(const char 
             }
      }
     
     if (*result) return mystrdup(result);
     return NULL;
 }
 
 SfxEntry::SfxEntry(AffixMgr * pmgr, affentry* dp)
+    : pmyMgr(pmgr) // register affix manager
+    , next(NULL)
+    , nexteq(NULL)
+    , nextne(NULL)
+    , flgnxt(NULL)
+    , l_morph(NULL)
+    , r_morph(NULL)
+    , eq_morph(NULL)
 {
-  // register affix manager
-  pmyMgr = pmgr;
-
   // set up its initial values
   aflag = dp->aflag;         // char flag
   strip = dp->strip;         // string to strip
   appnd = dp->appnd;         // string to append
   stripl = dp->stripl;       // length of strip string
   appndl = dp->appndl;       // length of append string
   numconds = dp->numconds;   // length of the condition
   opts = dp->opts;           // cross product flag
 
   // then copy over all of the conditions
   if (opts & aeLONGCOND) {
     memcpy(c.l.conds1, dp->c.l.conds1, MAXCONDLEN_1);
     c.l.conds2 = dp->c.l.conds2;
   } else memcpy(c.conds, dp->c.conds, MAXCONDLEN);
-  next = NULL;
-  nextne = NULL;
-  nexteq = NULL;
   rappnd = myrevstrdup(appnd);
   morphcode = dp->morphcode;
   contclass = dp->contclass;
   contclasslen = dp->contclasslen;
 }
 
 
 SfxEntry::~SfxEntry()
@@ -489,25 +453,26 @@ SfxEntry::~SfxEntry()
     if (opts & aeLONGCOND) free(c.l.conds2);
     if (morphcode && !(opts & aeALIASM)) free(morphcode);
     if (contclass && !(opts & aeALIASF)) free(contclass);
 }
 
 // add suffix to this word assuming conditions hold
 char * SfxEntry::add(const char * word, int len)
 {
-    char                tword[MAXWORDUTF8LEN + 4];
+    char tword[MAXTEMPWORDLEN];
 
      /* make sure all conditions match */
      if ((len > stripl || (len == 0 && pmyMgr->get_fullstrip())) &&
         (len >= numconds) && test_condition(word + len, word) &&
         (!stripl || (strcmp(word + len - stripl, strip) == 0)) &&
-        ((MAXWORDUTF8LEN + 4) > (len + appndl - stripl))) {
+        ((MAXTEMPWORDLEN) > (len + appndl - stripl))) {
               /* we have a match so add suffix */
-              strcpy(tword,word);
+              strncpy(tword, word, MAXTEMPWORDLEN-1);
+              tword[MAXTEMPWORDLEN-1] = '\0';
               if (appndl) {
                   strcpy(tword + len - stripl, appnd);
               } else {
                   *(tword + len - stripl) = '\0';
               }
               return mystrdup(tword);
      }
      return NULL;
@@ -532,48 +497,62 @@ inline int SfxEntry::test_condition(cons
     bool neg = false;           // complementer
     bool ingroup = false;       // character in the group
     if (numconds == 0) return 1;
     char * p = c.conds;
     st--;
     int i = 1;
     while (1) {
       switch (*p) {
-        case '\0': return 1;
-        case '[': { p = nextchar(p); pos = st; break; }
-        case '^': { p = nextchar(p); neg = true; break; }
-        case ']': { if (!neg && !ingroup) return 0;
-                i++;
-                // skip the next character
-                if (!ingroup) {
-                    for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
-                    st--;
-                }                    
-                pos = NULL;
-                neg = false;
-                ingroup = false;
-                p = nextchar(p);
-                if (st < beg && p) return 0; // word <= condition
-                break;
-            }
-        case '.': if (!pos) { // dots are not metacharacters in groups: [.]
+        case '\0':
+            return 1;
+        case '[':
+            p = nextchar(p);
+            pos = st;
+            break;
+        case '^':
+            p = nextchar(p);
+            neg = true;
+            break;
+        case ']':
+            if (!neg && !ingroup)
+              return 0;
+            i++;
+            // skip the next character
+            if (!ingroup)
+            {
+                for (; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
+                st--;
+            }                    
+            pos = NULL;
+            neg = false;
+            ingroup = false;
+            p = nextchar(p);
+            if (st < beg && p)
+                return 0; // word <= condition
+            break;
+        case '.':
+            if (!pos)
+            {
+                // dots are not metacharacters in groups: [.]
                 p = nextchar(p);
                 // skip the next character
                 for (st--; (opts & aeUTF8) && (st >= beg) && (*st & 0xc0) == 0x80; st--);
                 if (st < beg) { // word <= condition
 		    if (p) return 0; else return 1;
 		}
                 if ((opts & aeUTF8) && (*st & 0x80)) { // head of the UTF-8 character
                     st--;
                     if (st < beg) { // word <= condition
 			if (p) return 0; else return 1;
 		    }
                 }
                 break;
             }
+            /* FALLTHROUGH */
     default: {
                 if (*st == *p) {
                     p = nextchar(p);
                     if ((opts & aeUTF8) && (*st & 0x80)) {
                         st--;
                         while (p && (st >= beg)) {
                             if (*p != *st) {
                                 if (!pos) return 0;
@@ -584,26 +563,26 @@ inline int SfxEntry::test_condition(cons
                             if ((*p & 0xc0) != 0x80) break;
                             p = nextchar(p);
                             st--;
                         }
                         if (pos && st != pos) {
                             if (neg) return 0;
                             else if (i == numconds) return 1;
                             ingroup = true;
-                            while (p && *p != ']' && (p = nextchar(p)));
+                            while (p && *p != ']' && ((p = nextchar(p)) != NULL));
 			    st--;
                         }
                         if (p && *p != ']') p = nextchar(p);
                     } else if (pos) {
                         if (neg) return 0;
                         else if (i == numconds) return 1;
                         ingroup = true;
-			while (p && *p != ']' && (p = nextchar(p)))
-                          ;
+			while (p && *p != ']' && ((p = nextchar(p)) != NULL))
+                           ;
 //			if (p && *p != ']') p = nextchar(p);
                         st--;
                     }
                     if (!pos) {
                         i++;
                         st--;
                     }
                     if (st < beg && p && *p != ']') return 0; // word <= condition
@@ -619,17 +598,17 @@ inline int SfxEntry::test_condition(cons
 // see if this suffix is present in the word
 struct hentry * SfxEntry::checkword(const char * word, int len, int optflags,
     PfxEntry* ppfx, char ** wlst, int maxSug, int * ns, const FLAG cclass, const FLAG needflag,
     const FLAG badflag)
 {
     int                 tmpl;            // length of tmpword
     struct hentry *     he;              // hash entry pointer
     unsigned char *     cp;
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
     PfxEntry* ep = ppfx;
 
     // if this suffix is being cross checked with a prefix
     // but it does not support cross products skip it
 
     if (((optflags & aeXPRODUCT) != 0) && ((opts & aeXPRODUCT) == 0))
         return NULL;
 
@@ -644,17 +623,18 @@ struct hentry * SfxEntry::checkword(cons
 
     if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
         (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing suffix and adding
             // back any characters that would have been stripped or
             // or null terminating the shorter string
 
-            strcpy (tmpword, word);
+            strncpy (tmpword, word, MAXTEMPWORDLEN-1);
+            tmpword[MAXTEMPWORDLEN-1] = '\0';
             cp = (unsigned char *)(tmpword + tmpl);
             if (stripl) {
                 strcpy ((char *)cp, strip);
                 tmpl += stripl;
                 cp = (unsigned char *)(tmpword + tmpl);
             } else *cp = '\0';
 
             // now make sure all of the conditions on characters
@@ -697,17 +677,20 @@ struct hentry * SfxEntry::checkword(cons
                     } while (he);
 
                 // obsolote stemming code (used only by the
                 // experimental SuffixMgr:suggest_pos_stems)
                 // store resulting root in wlst
                 } else if (wlst && (*ns < maxSug)) {
                     int cwrd = 1;
                     for (int k=0; k < *ns; k++)
-                        if (strcmp(tmpword, wlst[k]) == 0) cwrd = 0;
+                        if (strcmp(tmpword, wlst[k]) == 0) {
+                           cwrd = 0;
+                           break;
+                        }
                     if (cwrd) {
                         wlst[*ns] = mystrdup(tmpword);
                         if (wlst[*ns] == NULL) {
                             for (int j=0; j<*ns; j++) free(wlst[j]);
                             *ns = -1;
                             return NULL;
                         }
                         (*ns)++;
@@ -720,17 +703,17 @@ struct hentry * SfxEntry::checkword(cons
 
 // see if two-level suffix is present in the word
 struct hentry * SfxEntry::check_twosfx(const char * word, int len, int optflags,
     PfxEntry* ppfx, const FLAG needflag)
 {
     int                 tmpl;            // length of tmpword
     struct hentry *     he;              // hash entry pointer
     unsigned char *     cp;
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
     PfxEntry* ep = ppfx;
 
 
     // if this suffix is being cross checked with a prefix
     // but it does not support cross products skip it
 
     if ((optflags & aeXPRODUCT) != 0 &&  (opts & aeXPRODUCT) == 0)
         return NULL;
@@ -744,17 +727,18 @@ struct hentry * SfxEntry::check_twosfx(c
 
     if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
        (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing suffix and adding
             // back any characters that would have been stripped or
             // or null terminating the shorter string
 
-            strcpy (tmpword, word);
+            strncpy(tmpword, word, MAXTEMPWORDLEN-1);
+            tmpword[MAXTEMPWORDLEN-1] = '\0';
             cp = (unsigned char *)(tmpword + tmpl);
             if (stripl) {
                 strcpy ((char *)cp, strip);
                 tmpl += stripl;
                 cp = (unsigned char *)(tmpword + tmpl);
             } else *cp = '\0';
 
             // now make sure all of the conditions on characters
@@ -781,17 +765,17 @@ struct hentry * SfxEntry::check_twosfx(c
 }
 
 // see if two-level suffix is present in the word
 char * SfxEntry::check_twosfx_morph(const char * word, int len, int optflags,
     PfxEntry* ppfx, const FLAG needflag)
 {
     int                 tmpl;            // length of tmpword
     unsigned char *     cp;
-    char                tmpword[MAXWORDUTF8LEN + 4];
+    char                tmpword[MAXTEMPWORDLEN];
     PfxEntry* ep = ppfx;
     char * st;
 
     char result[MAXLNLEN];
 
     *result = '\0';
 
     // if this suffix is being cross checked with a prefix
@@ -809,17 +793,18 @@ char * SfxEntry::check_twosfx_morph(cons
 
     if ((tmpl > 0 || (tmpl == 0 && pmyMgr->get_fullstrip())) &&
        (tmpl + stripl >= numconds)) {
 
             // generate new root word by removing suffix and adding
             // back any characters that would have been stripped or
             // or null terminating the shorter string
 
-            strcpy (tmpword, word);
+            strncpy(tmpword, word, MAXTEMPWORDLEN-1);
+            tmpword[MAXTEMPWORDLEN-1] = '\0';
             cp = (unsigned char *)(tmpword + tmpl);
             if (stripl) {
                 strcpy ((char *)cp, strip);
                 tmpl += stripl;
                 cp = (unsigned char *)(tmpword + tmpl);
             } else *cp = '\0';
 
             // now make sure all of the conditions on characters
--- a/extensions/spellcheck/hunspell/src/affentry.hxx
+++ b/extensions/spellcheck/hunspell/src/affentry.hxx
@@ -1,78 +1,25 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _AFFIX_HXX_
 #define _AFFIX_HXX_
 
 #include "hunvisapi.h"
 
 #include "atypes.hxx"
 #include "baseaffix.hxx"
 #include "affixmgr.hxx"
 
 /* A Prefix Entry  */
 
 class LIBHUNSPELL_DLL_EXPORTED PfxEntry : protected AffEntry
 {
+private:
+       PfxEntry(const PfxEntry&);
+       PfxEntry& operator = (const PfxEntry&);
+private:
        AffixMgr*    pmyMgr;
 
        PfxEntry * next;
        PfxEntry * nexteq;
        PfxEntry * nextne;
        PfxEntry * flgnxt;
 
 public:
@@ -119,16 +66,20 @@ public:
 
 
 
 
 /* A Suffix Entry */
 
 class LIBHUNSPELL_DLL_EXPORTED SfxEntry : protected AffEntry
 {
+private:
+       SfxEntry(const SfxEntry&);
+       SfxEntry& operator = (const SfxEntry&);
+private:
        AffixMgr*    pmyMgr;
        char *       rappnd;
 
        SfxEntry *   next;
        SfxEntry *   nexteq;
        SfxEntry *   nextne;
        SfxEntry *   flgnxt;
            
--- a/extensions/spellcheck/hunspell/src/affixmgr.cxx
+++ b/extensions/spellcheck/hunspell/src/affixmgr.cxx
@@ -1,64 +1,10 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 #include <ctype.h>
 
 #include <vector>
 
@@ -97,16 +43,17 @@ AffixMgr::AffixMgr(const char * affpath,
   phone = NULL;
   compoundflag = FLAG_NULL; // permits word in compound forms
   compoundbegin = FLAG_NULL; // may be first word in compound forms
   compoundmiddle = FLAG_NULL; // may be middle word in compound forms
   compoundend = FLAG_NULL; // may be last word in compound forms
   compoundroot = FLAG_NULL; // compound word signing flag
   compoundpermitflag = FLAG_NULL; // compound permitting flag for suffixed word
   compoundforbidflag = FLAG_NULL; // compound fordidden flag for suffixed word
+  compoundmoresuffixes = 0; // allow more suffixes within compound words
   checkcompounddup = 0; // forbid double words in compounds
   checkcompoundrep = 0; // forbid bad compounds (may be non compound word with a REP substitution)
   checkcompoundcase = 0; // forbid upper and lowercase combinations at word bounds
   checkcompoundtriple = 0; // forbid compounds with triple letters
   simplifiedtriple = 0; // allow simplified triple letters in compounds (Schiff+fahrt -> Schiffahrt)
   forbiddenword = FORBIDDENWORD; // forbidden word signing flag
   nosuggest = FLAG_NULL; // don't suggest words signed with NOSUGGEST flag
   nongramsuggest = FLAG_NULL;
@@ -302,16 +249,24 @@ AffixMgr::~AffixMgr()
   if (ignorechars_utf16) free(ignorechars_utf16);
   if (version) free(version);
   checknum=0;
 #ifdef MOZILLA_CLIENT
   delete [] csconv;
 #endif
 }
 
+void AffixMgr::finishFileMgr(FileMgr *afflst)
+{
+    delete afflst;
+
+    // convert affix trees to sorted list
+    process_pfx_tree_to_list();
+    process_sfx_tree_to_list();
+}
 
 // read in aff file and build up prefix and suffix entry objects 
 int  AffixMgr::parse_file(const char * affpath, const char * key)
 {
   char * line; // io buffers
   char ft;     // affix type
   
   // checking flag duplication
@@ -328,48 +283,48 @@ int  AffixMgr::parse_file(const char * a
     return 1;
   }
 
   // step one is to parse the affix file building up the internal
   // affix data structures
 
     // read in each line ignoring any that do not
     // start with a known line type indicator
-    while ((line = afflst->getline())) {
+    while ((line = afflst->getline()) != NULL) {
        mychomp(line);
 
        /* remove byte order mark */
        if (firstline) {
          firstline = 0;
          // Affix file begins with byte order mark: possible incompatibility with old Hunspell versions
          if (strncmp(line,"\xEF\xBB\xBF",3) == 0) {
             memmove(line, line+3, strlen(line+3)+1);
          }
        }
 
        /* parse in the keyboard string */
        if (strncmp(line,"KEY",3) == 0) {
           if (parse_string(line, &keystring, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the try string */
        if (strncmp(line,"TRY",3) == 0) {
           if (parse_string(line, &trystring, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the name of the character set used by the .dict and .aff */
        if (strncmp(line,"SET",3) == 0) {
           if (parse_string(line, &encoding, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
           if (strcmp(encoding, "UTF-8") == 0) {
              utf8 = 1;
 #ifndef OPENOFFICEORG
 #ifndef MOZILLA_CLIENT
              if (initialize_utf_tbl()) return 1;
 #endif
@@ -379,90 +334,94 @@ int  AffixMgr::parse_file(const char * a
 
        /* parse COMPLEXPREFIXES for agglutinative languages with right-to-left writing system */
        if (strncmp(line,"COMPLEXPREFIXES",15) == 0)
                    complexprefixes = 1;
 
        /* parse in the flag used by the controlled compound words */
        if (strncmp(line,"COMPOUNDFLAG",12) == 0) {
           if (parse_flag(line, &compoundflag, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by compound words */
        if (strncmp(line,"COMPOUNDBEGIN",13) == 0) {
           if (complexprefixes) {
             if (parse_flag(line, &compoundend, afflst)) {
-              delete afflst;
+              finishFileMgr(afflst);
               return 1;
             }
           } else {
             if (parse_flag(line, &compoundbegin, afflst)) {
-              delete afflst;
+              finishFileMgr(afflst);
               return 1;
             }
           }
        }
 
        /* parse in the flag used by compound words */
        if (strncmp(line,"COMPOUNDMIDDLE",14) == 0) {
           if (parse_flag(line, &compoundmiddle, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
        /* parse in the flag used by compound words */
        if (strncmp(line,"COMPOUNDEND",11) == 0) {
           if (complexprefixes) {
             if (parse_flag(line, &compoundbegin, afflst)) {
-              delete afflst;
+              finishFileMgr(afflst);
               return 1;
             }
           } else {
             if (parse_flag(line, &compoundend, afflst)) {
-              delete afflst;
+              finishFileMgr(afflst);
               return 1;
             }
           }
        }
 
        /* parse in the data used by compound_check() method */
        if (strncmp(line,"COMPOUNDWORDMAX",15) == 0) {
           if (parse_num(line, &cpdwordmax, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag sign compounds in dictionary */
        if (strncmp(line,"COMPOUNDROOT",12) == 0) {
           if (parse_flag(line, &compoundroot, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by compound_check() method */
        if (strncmp(line,"COMPOUNDPERMITFLAG",18) == 0) {
           if (parse_flag(line, &compoundpermitflag, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by compound_check() method */
        if (strncmp(line,"COMPOUNDFORBIDFLAG",18) == 0) {
           if (parse_flag(line, &compoundforbidflag, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
+       if (strncmp(line,"COMPOUNDMORESUFFIXES",20) == 0) {
+                   compoundmoresuffixes = 1;
+       }
+
        if (strncmp(line,"CHECKCOMPOUNDDUP",16) == 0) {
                    checkcompounddup = 1;
        }
 
        if (strncmp(line,"CHECKCOMPOUNDREP",16) == 0) {
                    checkcompoundrep = 1;
        }
 
@@ -475,220 +434,220 @@ int  AffixMgr::parse_file(const char * a
        }
 
        if (strncmp(line,"CHECKCOMPOUNDCASE",17) == 0) {
                    checkcompoundcase = 1;
        }
 
        if (strncmp(line,"NOSUGGEST",9) == 0) {
           if (parse_flag(line, &nosuggest, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"NONGRAMSUGGEST",14) == 0) {
           if (parse_flag(line, &nongramsuggest, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by forbidden words */
        if (strncmp(line,"FORBIDDENWORD",13) == 0) {
           if (parse_flag(line, &forbiddenword, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by forbidden words */
        if (strncmp(line,"LEMMA_PRESENT",13) == 0) {
           if (parse_flag(line, &lemma_present, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by circumfixes */
        if (strncmp(line,"CIRCUMFIX",9) == 0) {
           if (parse_flag(line, &circumfix, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by fogemorphemes */
        if (strncmp(line,"ONLYINCOMPOUND",14) == 0) {
           if (parse_flag(line, &onlyincompound, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by `needaffixs' */
        if (strncmp(line,"PSEUDOROOT",10) == 0) {
           if (parse_flag(line, &needaffix, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by `needaffixs' */
        if (strncmp(line,"NEEDAFFIX",9) == 0) {
           if (parse_flag(line, &needaffix, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the minimal length for words in compounds */
        if (strncmp(line,"COMPOUNDMIN",11) == 0) {
           if (parse_num(line, &cpdmin, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
           if (cpdmin < 1) cpdmin = 1;
        }
 
        /* parse in the max. words and syllables in compounds */
        if (strncmp(line,"COMPOUNDSYLLABLE",16) == 0) {
           if (parse_cpdsyllable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by compound_check() method */
        if (strncmp(line,"SYLLABLENUM",11) == 0) {
           if (parse_string(line, &cpdsyllablenum, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by the controlled compound words */
        if (strncmp(line,"CHECKNUM",8) == 0) {
            checknum=1;
        }
 
        /* parse in the extra word characters */
        if (strncmp(line,"WORDCHARS",9) == 0) {
           if (parse_array(line, &wordchars, &wordchars_utf16, &wordchars_utf16_len, utf8, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the ignored characters (for example, Arabic optional diacretics charachters */
        if (strncmp(line,"IGNORE",6) == 0) {
           if (parse_array(line, &ignorechars, &ignorechars_utf16, &ignorechars_utf16_len, utf8, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the typical fault correcting table */
        if (strncmp(line,"REP",3) == 0) {
           if (parse_reptable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the input conversion table */
        if (strncmp(line,"ICONV",5) == 0) {
           if (parse_convtable(line, afflst, &iconvtable, "ICONV")) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the input conversion table */
        if (strncmp(line,"OCONV",5) == 0) {
           if (parse_convtable(line, afflst, &oconvtable, "OCONV")) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the phonetic translation table */
        if (strncmp(line,"PHONE",5) == 0) {
           if (parse_phonetable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the checkcompoundpattern table */
        if (strncmp(line,"CHECKCOMPOUNDPATTERN",20) == 0) {
           if (parse_checkcpdtable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the defcompound table */
        if (strncmp(line,"COMPOUNDRULE",12) == 0) {
           if (parse_defcpdtable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the related character map table */
        if (strncmp(line,"MAP",3) == 0) {
           if (parse_maptable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the word breakpoints table */
        if (strncmp(line,"BREAK",5) == 0) {
           if (parse_breaktable(line, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the language for language specific codes */
        if (strncmp(line,"LANG",4) == 0) {
           if (parse_string(line, &lang, afflst->getlinenum())) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
           langnum = get_lang_num(lang);
        }
 
        if (strncmp(line,"VERSION",7) == 0) {
           for(line = line + 7; *line == ' ' || *line == '\t'; line++);
           version = mystrdup(line);
        }
 
        if (strncmp(line,"MAXNGRAMSUGS",12) == 0) {
           if (parse_num(line, &maxngramsugs, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"ONLYMAXDIFF", 11) == 0)
                    onlymaxdiff = 1;
 
        if (strncmp(line,"MAXDIFF",7) == 0) {
           if (parse_num(line, &maxdiff, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"MAXCPDSUGS",10) == 0) {
           if (parse_num(line, &maxcpdsugs, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"NOSPLITSUGS",11) == 0) {
                    nosplitsugs=1;
        }
 
@@ -698,45 +657,45 @@ int  AffixMgr::parse_file(const char * a
 
        if (strncmp(line,"SUGSWITHDOTS",12) == 0) {
                    sugswithdots=1;
        }
 
        /* parse in the flag used by forbidden words */
        if (strncmp(line,"KEEPCASE",8) == 0) {
           if (parse_flag(line, &keepcase, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by `forceucase' */
        if (strncmp(line,"FORCEUCASE",10) == 0) {
           if (parse_flag(line, &forceucase, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        /* parse in the flag used by `warn' */
        if (strncmp(line,"WARN",4) == 0) {
           if (parse_flag(line, &warn, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"FORBIDWARN",10) == 0) {
                    forbidwarn=1;
        }
 
        /* parse in the flag used by the affix generator */
        if (strncmp(line,"SUBSTANDARD",11) == 0) {
           if (parse_flag(line, &substandard, afflst)) {
-             delete afflst;
+             finishFileMgr(afflst);
              return 1;
           }
        }
 
        if (strncmp(line,"CHECKSHARPS",11) == 0) {
                    checksharps=1;
        }
 
@@ -745,29 +704,24 @@ int  AffixMgr::parse_file(const char * a
        if (strncmp(line,"PFX",3) == 0) ft = complexprefixes ? 'S' : 'P';
        if (strncmp(line,"SFX",3) == 0) ft = complexprefixes ? 'P' : 'S';
        if (ft != ' ') {
           if (dupflags_ini) {
             memset(dupflags, 0, sizeof(dupflags));
             dupflags_ini = 0;
           }
           if (parse_affix(line, ft, afflst, dupflags)) {
-             delete afflst;
-             process_pfx_tree_to_list();
-             process_sfx_tree_to_list();
+             finishFileMgr(afflst);
              return 1;
           }
        }
-
     }
-    delete afflst;
-
-    // convert affix trees to sorted list
-    process_pfx_tree_to_list();
-    process_sfx_tree_to_list();
+
+    finishFileMgr(afflst);
+    // affix trees are sorted now
 
     // now we can speed up performance greatly taking advantage of the 
     // relationship between the affixes and the idea of "subsets".
 
     // View each prefix as a potential leading subset of another and view
     // each suffix (reversed) as a potential trailing subset of another.
 
     // To illustrate this relationship if we know the prefix "ab" is found in the
@@ -1368,30 +1322,30 @@ int AffixMgr::cpdrep_check(const char * 
           if (candidate_check(candidate,strlen(candidate))) return 1;
           r++; // search for the next letter
       }
    }
    return 0;
 }
 
 // forbid compoundings when there are special patterns at word bound
-int AffixMgr::cpdpat_check(const char * word, int pos, hentry * r1, hentry * r2, const char affixed)
+int AffixMgr::cpdpat_check(const char * word, int pos, hentry * r1, hentry * r2, const char /*affixed*/)
 {
   int len;
   for (int i = 0; i < numcheckcpd; i++) {
       if (isSubset(checkcpdtable[i].pattern2, word + pos) &&
         (!r1 || !checkcpdtable[i].cond ||
           (r1->astr && TESTAFF(r1->astr, checkcpdtable[i].cond, r1->alen))) &&
         (!r2 || !checkcpdtable[i].cond2 ||
           (r2->astr && TESTAFF(r2->astr, checkcpdtable[i].cond2, r2->alen))) &&
         // zero length pattern => only TESTAFF
         // zero pattern (0/flag) => unmodified stem (zero affixes allowed)
         (!*(checkcpdtable[i].pattern) || (
             (*(checkcpdtable[i].pattern)=='0' && r1->blen <= pos && strncmp(word + pos - r1->blen, r1->word, r1->blen) == 0) ||
-            (*(checkcpdtable[i].pattern)!='0' && (len = strlen(checkcpdtable[i].pattern)) &&
+            (*(checkcpdtable[i].pattern)!='0' && ((len = strlen(checkcpdtable[i].pattern)) != 0) &&
                 strncmp(word + pos - len, checkcpdtable[i].pattern, len) == 0)))) {
             return 1;
         }
   }
   return 0;
 }
 
 // forbid compounding with neighbouring upper and lower case characters at word bounds
@@ -1442,17 +1396,20 @@ int AffixMgr::defcpd_check(hentry *** wo
     (*words)[wnum] = NULL;
     if (w) *words = NULL;
     return 0;
   }
   ok = 0;
   for (i = 0; i < numdefcpd; i++) {
     for (j = 0; j < defcpdtable[i].len; j++) {
        if (defcpdtable[i].def[j] != '*' && defcpdtable[i].def[j] != '?' &&
-          TESTAFF(rv->astr, defcpdtable[i].def[j], rv->alen)) ok = 1;
+          TESTAFF(rv->astr, defcpdtable[i].def[j], rv->alen)) {
+         ok = 1;
+         break;
+       }
     }
   }
   if (ok == 0) {
     (*words)[wnum] = NULL;
     if (w) *words = NULL;
     return 0;
   }
 
@@ -1593,17 +1550,17 @@ struct hentry * AffixMgr::compound_check
     int striple = 0;
     int scpd = 0;
     int soldi = 0;
     int oldcmin = 0;
     int oldcmax = 0;
     int oldlen = 0;
     int checkedstriple = 0;
     int onlycpdrule;
-    int affixed = 0;
+    char affixed = 0;
     hentry ** oldwords = words;
 
     int checked_prefix;
 
     setcminmax(&cmin, &cmax, word, len);
 
     strcpy(st, word);
 
@@ -1675,33 +1632,36 @@ struct hentry * AffixMgr::compound_check
         }
 
         if (rv) affixed = 0;
 
         if (!rv) {
             if (onlycpdrule) break;
             if (compoundflag && 
              !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
-                if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
-                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
+                if (((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
+                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) || 
+                        (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundflag)))) && !hu_mov_rule &&
                     sfx->getCont() &&
                         ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, 
                             sfx->getContLen())) || (compoundend &&
                         TESTAFF(sfx->getCont(), compoundend, 
                             sfx->getContLen())))) {
                         rv = NULL;
                 }
             }
 
             if (rv ||
               (((wordnum == 0) && compoundbegin &&
                 ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+                (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundbegin))) || // twofold suffixes + compound
                 (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
               ((wordnum > 0) && compoundmiddle &&
                 ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+                (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundmiddle))) || // twofold suffixes + compound
                 (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
               ) checked_prefix = 1;
         // else check forbiddenwords and needaffix
         } else if (rv->astr && (TESTAFF(rv->astr, forbiddenword, rv->alen) ||
             TESTAFF(rv->astr, needaffix, rv->alen) ||
             TESTAFF(rv->astr, ONLYUPCASEFLAG, rv->alen) ||
             (is_sug && nosuggest && TESTAFF(rv->astr, nosuggest, rv->alen))
              )) {
@@ -2094,17 +2054,17 @@ int AffixMgr::compound_check_morph(const
 
     int checked_prefix;
     char presult[MAXLNLEN];
 
     int cmin;
     int cmax;
 
     int onlycpdrule;
-    int affixed = 0;
+    char affixed = 0;
     hentry ** oldwords = words;
 
     setcminmax(&cmin, &cmax, word, len);
 
     strcpy(st, word);
 
     for (i = cmin; i < cmax; i++) {
         oldnumsyllable = numsyllable;
@@ -2164,36 +2124,39 @@ int AffixMgr::compound_check_morph(const
             // store the pointer of the hash entry
 //            sprintf(presult + strlen(presult), "%c%s%p", MSEP_FLD, MORPH_HENTRY, rv);
             if (HENTRY_DATA(rv)) {
                 sprintf(presult + strlen(presult), "%c%s", MSEP_FLD, HENTRY_DATA2(rv));
             }
         }        
 
         if (!rv) {
-            if (onlycpdrule) break;
+            if (onlycpdrule && strlen(*result) > MAXLNLEN/10) break;
             if (compoundflag &&
              !(rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundflag))) {
-                if ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
-                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) && !hu_mov_rule &&
+                if (((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL,
+                        FLAG_NULL, compoundflag, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+                        (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundflag)))) && !hu_mov_rule &&
                     sfx->getCont() &&
                         ((compoundforbidflag && TESTAFF(sfx->getCont(), compoundforbidflag, 
                             sfx->getContLen())) || (compoundend &&
                         TESTAFF(sfx->getCont(), compoundend, 
                             sfx->getContLen())))) {
                         rv = NULL;
                 }
             }
 
             if (rv ||
               (((wordnum == 0) && compoundbegin &&
                 ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundbegin, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+                (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundbegin))) ||  // twofold suffix+compound
                 (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundbegin)))) ||
               ((wordnum > 0) && compoundmiddle &&
                 ((rv = suffix_check(st, i, 0, NULL, NULL, 0, NULL, FLAG_NULL, compoundmiddle, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN)) ||
+                (compoundmoresuffixes && (rv = suffix_check_twosfx(st, i, 0, NULL, compoundmiddle))) ||  // twofold suffix+compound
                 (rv = prefix_check(st, i, hu_mov_rule ? IN_CPD_OTHER : IN_CPD_BEGIN, compoundmiddle)))))
               ) {
                 // char * p = prefix_check_morph(st, i, 0, compound);
                 char * p = NULL;
                 if (compoundflag) p = affix_check_morph(st, i, compoundflag);
                 if (!p || (*p == '\0')) {
                    if (p) free(p);
                    p = NULL;
@@ -3603,17 +3566,17 @@ int  AffixMgr::parse_reptable(char * lin
    if (np != 2) {
       HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum());
       return 1;
    } 
  
    /* now parse the numrep lines to read in the remainder of the table */
    char * nl;
    for (int j=0; j < numrep; j++) {
-        if (!(nl = af->getline())) return 1;
+        if ((nl = af->getline()) == NULL) return 1;
         mychomp(nl);
         tp = nl;
         i = 0;
         reptable[j].pattern = NULL;
         reptable[j].pattern2 = NULL;
         piece = mystrsep(&tp, 0);
         while (piece) {
            if (*piece != '\0') {
@@ -4307,17 +4270,17 @@ int  AffixMgr::parse_affix(char * line, 
        }
        return 1;
    }
  
    // now parse numents affentries for this affix
    std::vector<affentry>::iterator start = affentries.begin();
    std::vector<affentry>::iterator end = affentries.end();
    for (std::vector<affentry>::iterator entry = start; entry != end; ++entry) {
-      if (!(nl = af->getline())) return 1;
+      if ((nl = af->getline()) == NULL) return 1;
       mychomp(nl);
       tp = nl;
       i = 0;
       np = 0;
 
       // split line into pieces
       piece = mystrsep(&tp, 0);
       while (piece) {
--- a/extensions/spellcheck/hunspell/src/affixmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/affixmgr.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _AFFIXMGR_HXX_
 #define _AFFIXMGR_HXX_
 
 #include "hunvisapi.h"
 
 #include <stdio.h>
 
 #include "atypes.hxx"
@@ -93,16 +36,17 @@ class LIBHUNSPELL_DLL_EXPORTED AffixMgr
   int                 complexprefixes;
   FLAG                compoundflag;
   FLAG                compoundbegin;
   FLAG                compoundmiddle;
   FLAG                compoundend;
   FLAG                compoundroot;
   FLAG                compoundforbidflag;
   FLAG                compoundpermitflag;
+  int                 compoundmoresuffixes;
   int                 checkcompounddup;
   int                 checkcompoundrep;
   int                 checkcompoundcase;
   int                 checkcompoundtriple;
   int                 simplifiedtriple;
   FLAG                forbiddenword;
   FLAG                nosuggest;
   FLAG                nongramsuggest;
@@ -296,12 +240,13 @@ private:
   int process_pfx_order();
   int process_sfx_order();
   PfxEntry * process_pfx_in_order(PfxEntry * ptr, PfxEntry * nptr);
   SfxEntry * process_sfx_in_order(SfxEntry * ptr, SfxEntry * nptr);
   int process_pfx_tree_to_list();
   int process_sfx_tree_to_list();
   int redundant_condition(char, char * strip, int stripl,
       const char * cond, int);
+  void finishFileMgr(FileMgr *afflst);
 };
 
 #endif
 
--- a/extensions/spellcheck/hunspell/src/atypes.hxx
+++ b/extensions/spellcheck/hunspell/src/atypes.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _ATYPES_HXX_
 #define _ATYPES_HXX_
 
 #ifndef HUNSPELL_WARNING
 #include <stdio.h>
 #ifdef HUNSPELL_WARNING_ON
 #define HUNSPELL_WARNING fprintf
 #else
@@ -109,17 +52,17 @@ static inline void HUNSPELL_WARNING(FILE
 #define MAXCONDLEN_1    (MAXCONDLEN - sizeof(char *))
 
 #define MAXACC          1000
 
 #define FLAG unsigned short
 #define FLAG_NULL 0x00
 #define FREE_FLAG(a) a = 0
 
-#define TESTAFF( a, b , c ) flag_bsearch((unsigned short *) a, (unsigned short) b, c)
+#define TESTAFF( a, b , c ) (flag_bsearch((unsigned short *) a, (unsigned short) b, c))
 
 struct affentry
 {
    char * strip;
    char * appnd;
    unsigned char stripl;
    unsigned char appndl;
    char  numconds;
--- a/extensions/spellcheck/hunspell/src/baseaffix.hxx
+++ b/extensions/spellcheck/hunspell/src/baseaffix.hxx
@@ -1,73 +1,20 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _BASEAFF_HXX_
 #define _BASEAFF_HXX_
 
 #include "hunvisapi.h"
 
 class LIBHUNSPELL_DLL_EXPORTED AffEntry
 {
+private:
+    AffEntry(const AffEntry&);
+    AffEntry& operator = (const AffEntry&);
 protected:
+    AffEntry() {}
     char *         appnd;
     char *         strip;
     unsigned char  appndl;
     unsigned char  stripl;
     char           numconds;
     char           opts;
     unsigned short aflag;
     union {
--- a/extensions/spellcheck/hunspell/src/csutil.cxx
+++ b/extensions/spellcheck/hunspell/src/csutil.cxx
@@ -1,65 +1,10 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 L. David Baron (dbaron@dbaron.org)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h> 
 #include <string.h>
 #include <stdio.h> 
 #include <ctype.h>
 
 #include "csutil.hxx"
 #include "atypes.hxx"
@@ -67,16 +12,21 @@
 
 // Unicode character encoding information
 struct unicode_info {
   unsigned short c;
   unsigned short cupper;
   unsigned short clower;
 };
 
+#ifdef _WIN32
+#include <windows.h>
+#include <wchar.h>
+#endif
+
 #ifdef OPENOFFICEORG
 #  include <unicode/uchar.h>
 #else
 #  ifndef MOZILLA_CLIENT
 #    include "utf_info.cxx"
 #    define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
 #  endif
 #endif
@@ -95,16 +45,31 @@ struct unicode_info2 {
   char cletter;
   unsigned short cupper;
   unsigned short clower;
 };
 
 static struct unicode_info2 * utf_tbl = NULL;
 static int utf_tbl_count = 0; // utf_tbl can be used by multiple Hunspell instances
 
+FILE * myfopen(const char * path, const char * mode) {
+#ifdef _WIN32
+#define WIN32_LONG_PATH_PREFIX "\\\\?\\"
+    if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
+        int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
+        wchar_t *buff = (wchar_t *) malloc(len * sizeof(wchar_t));
+        MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
+        FILE * f = _wfopen(buff, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
+        free(buff);
+        return f;
+    }
+#endif
+    return fopen(path, mode);
+}
+
 /* only UTF-16 (BMP) implementation */
 char * u16_u8(char * dest, int size, const w_char * src, int srclen) {
     signed char * u8 = (signed char *)dest;
     signed char * u8_max = (signed char *)(u8 + size);
     const w_char * u2 = src;
     const w_char * u2_max = src + srclen;
     while ((u2 < u2_max) && (u8 < u8_max)) {
         if (u2->h) { // > 0xFF
@@ -391,17 +356,20 @@ int line_tok(const char * text, char ***
 char * line_uniq(char * text, char breakchar) {
     char ** lines;
     int linenum = line_tok(text, &lines, breakchar);
     int i;
     strcpy(text, lines[0]);
     for ( i = 1; i < linenum; i++ ) {
         int dup = 0;
         for (int j = 0; j < i; j++) {
-            if (strcmp(lines[i], lines[j]) == 0) dup = 1;
+            if (strcmp(lines[i], lines[j]) == 0) {
+              dup = 1;
+              break;
+            }
         }
         if (!dup) {
             if ((i > 1) || (*(lines[0]) != '\0')) {
                 sprintf(text + strlen(text), "%c", breakchar);
             }
             strcat(text, lines[i]);
         }
     }
@@ -5526,16 +5494,17 @@ struct cs_info * get_current_cs(const ch
   // Initialze the array with dummy data so that we wouldn't need
   // to return null in case of failures.
   for (int i = 0; i <= 0xff; ++i) {
     ccs[i].ccase = false;
     ccs[i].clower = i;
     ccs[i].cupper = i;
   }
 
+
   nsCOMPtr<nsIUnicodeEncoder> encoder; 
   nsCOMPtr<nsIUnicodeDecoder> decoder; 
 
   nsresult rv;
 
   nsAutoCString label(es);
   nsAutoCString encoding;
   if (!EncodingUtils::FindEncodingForLabelNoReplacement(label, encoding)) {
@@ -5702,17 +5671,17 @@ void free_utf_tbl() {
 unsigned short unicodetoupper(unsigned short c, int langnum)
 {
   // In Azeri and Turkish, I and i dictinct letters:
   // There are a dotless lower case i pair of upper `I',
   // and an upper I with dot pair of lower `i'. 
   if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr)))
     return 0x0130;
 #ifdef OPENOFFICEORG
-  return u_toupper(c);
+  return static_cast<unsigned short>(u_toupper(c));
 #else
 #ifdef MOZILLA_CLIENT
   return ToUpperCase((char16_t) c);
 #else
   return (utf_tbl) ? utf_tbl[c].cupper : c;
 #endif
 #endif
 }
@@ -5720,17 +5689,17 @@ unsigned short unicodetoupper(unsigned s
 unsigned short unicodetolower(unsigned short c, int langnum)
 {
   // In Azeri and Turkish, I and i dictinct letters:
   // There are a dotless lower case i pair of upper `I',
   // and an upper I with dot pair of lower `i'. 
   if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr)))
     return 0x0131;
 #ifdef OPENOFFICEORG
-  return u_tolower(c);
+  return static_cast<unsigned short>(u_tolower(c));
 #else
 #ifdef MOZILLA_CLIENT
   return ToLowerCase((char16_t) c);
 #else
   return (utf_tbl) ? utf_tbl[c].clower : c;
 #endif
 #endif
 }
--- a/extensions/spellcheck/hunspell/src/csutil.hxx
+++ b/extensions/spellcheck/hunspell/src/csutil.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef __CSUTILHXX__
 #define __CSUTILHXX__
 
 #include "hunvisapi.h"
 
 // First some base level utility routines
 
 #include <string.h>
@@ -104,16 +47,19 @@
 #define MSEP_REC '\n'
 #define MSEP_ALT '\v'
 
 // default flags
 #define DEFAULTFLAGS   65510
 #define FORBIDDENWORD  65510
 #define ONLYUPCASEFLAG 65511
 
+// fopen or optional _wfopen to fix long pathname problem of WIN32
+LIBHUNSPELL_DLL_EXPORTED FILE * myfopen(const char * path, const char * mode);
+
 // convert UTF-16 characters to UTF-8
 LIBHUNSPELL_DLL_EXPORTED char * u16_u8(char * dest, int size, const w_char * src, int srclen);
 
 // convert UTF-8 characters to UTF-16
 LIBHUNSPELL_DLL_EXPORTED int u8_u16(w_char * dest, int size, const char * src);
 
 // sort 2-byte vector
 LIBHUNSPELL_DLL_EXPORTED void flag_qsort(unsigned short flags[], int begin, int end);
--- a/extensions/spellcheck/hunspell/src/dictmgr.cxx
+++ b/extensions/spellcheck/hunspell/src/dictmgr.cxx
@@ -1,48 +1,16 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
 
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 #include <stdio.h>
 
 #include "dictmgr.hxx"
+#include "csutil.hxx"
 
 DictMgr::DictMgr(const char * dictpath, const char * etype) : numdict(0)
 {
   // load list of etype entries
   pdentry = (dictentry *)malloc(MAXDICTIONARIES*sizeof(struct dictentry));
   if (pdentry) {
      if (parse_file(dictpath, etype)) {
         numdict = 0;
@@ -85,17 +53,17 @@ int  DictMgr::parse_file(const char * di
 {
 
     int i;
     char line[MAXDICTENTRYLEN+1];
     dictentry * pdict = pdentry;
 
     // open the dictionary list file
     FILE * dictlst;
-    dictlst = fopen(dictpath,"r");
+    dictlst = myfopen(dictpath,"r");
     if (!dictlst) {
       return 1;
     }
 
     // step one is to parse the dictionary list building up the 
     // descriptive structures
 
     // read in each line ignoring any that dont start with etype
@@ -128,17 +96,18 @@ int  DictMgr::parse_file(const char * di
              if (i == 4) {
                  numdict++;
                  pdict++;
              } else {
                  switch (i) {
                     case 3:
                        free(pdict->region);
                        pdict->region=NULL;
-                    case 2: //deliberate fallthrough
+                       /* FALLTHROUGH */
+                    case 2:
                        free(pdict->lang);
                        pdict->lang=NULL;
                     default:
                         break;
                  }
                  fprintf(stderr,"dictionary list corruption in line \"%s\"\n",line);
                  fflush(stderr);
              }
--- a/extensions/spellcheck/hunspell/src/dictmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/dictmgr.hxx
@@ -1,42 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _DICTMGR_HXX_
 #define _DICTMGR_HXX_
 
 #include "hunvisapi.h"
 
 #define MAXDICTIONARIES 100
 #define MAXDICTENTRYLEN 1024
 
@@ -44,17 +10,20 @@ struct dictentry {
   char * filename;
   char * lang;
   char * region;
 };
 
 
 class LIBHUNSPELL_DLL_EXPORTED DictMgr
 {
-
+private:
+  DictMgr(const DictMgr&);
+  DictMgr& operator = (const DictMgr&);
+private:
   int                 numdict;
   dictentry *         pdentry;
 
 public:
  
   DictMgr(const char * dictpath, const char * etype);
   ~DictMgr();
   int get_list(dictentry** ppentry);
--- a/extensions/spellcheck/hunspell/src/filemgr.cxx
+++ b/extensions/spellcheck/hunspell/src/filemgr.cxx
@@ -1,57 +1,30 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "filemgr.hxx"
+#include "csutil.hxx"
 
 int FileMgr::fail(const char * err, const char * par) {
     fprintf(stderr, err, par);
     return -1;
 }
 
-FileMgr::FileMgr(const char * file, const char * key) {
-    linenum = 0;
-    hin = NULL;
-    fin = fopen(file, "r");
+FileMgr::FileMgr(const char * file, const char * key)
+    : hin(NULL)
+    , linenum(0)
+{
+    in[0] = '\0';
+
+    fin = myfopen(file, "r");
     if (!fin) {
         // check hzipped file
         char * st = (char *) malloc(strlen(file) + strlen(HZIP_EXTENSION) + 1);
         if (st) {
             strcpy(st, file);
             strcat(st, HZIP_EXTENSION);
             hin = new Hunzip(st, key);
             free(st);
@@ -65,16 +38,16 @@ FileMgr::~FileMgr()
     if (fin) fclose(fin);
     if (hin) delete hin;
 }
 
 char * FileMgr::getline() {
     const char * l;
     linenum++;
     if (fin) return fgets(in, BUFSIZE - 1, fin);
-    if (hin && (l = hin->getline())) return strcpy(in, l);
+    if (hin && ((l = hin->getline()) != NULL)) return strcpy(in, l);
     linenum--;
     return NULL;
 }
 
 int FileMgr::getlinenum() {
     return linenum;
 }
--- a/extensions/spellcheck/hunspell/src/filemgr.hxx
+++ b/extensions/spellcheck/hunspell/src/filemgr.hxx
@@ -1,52 +1,22 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
+/* file manager class - read lines of files [filename] OR [filename.hz] */
 #ifndef _FILEMGR_HXX_
 #define _FILEMGR_HXX_
 
 #include "hunvisapi.h"
 
 #include "hunzip.hxx"
 #include <stdio.h>
 
 class LIBHUNSPELL_DLL_EXPORTED FileMgr
 {
+private:
+    FileMgr(const FileMgr&);
+    FileMgr& operator = (const FileMgr&);
 protected:
     FILE * fin;
     Hunzip * hin;
     char in[BUFSIZE + 50]; // input buffer
     int fail(const char * err, const char * par);
     int linenum;
 
 public:
--- a/extensions/spellcheck/hunspell/src/hashmgr.cxx
+++ b/extensions/spellcheck/hunspell/src/hashmgr.cxx
@@ -1,95 +1,44 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h> 
 #include <string.h>
 #include <stdio.h> 
 #include <ctype.h>
+#include <limits>
 
 #include "hashmgr.hxx"
 #include "csutil.hxx"
 #include "atypes.hxx"
 
 // build a hash table from a munched word list
 
 HashMgr::HashMgr(const char * tpath, const char * apath, const char * key)
+  : tablesize(0)
+  , tableptr(NULL)
+  , userword(0)
+  , flag_mode(FLAG_CHAR)
+  , complexprefixes(0)
+  , utf8(0)
+  , forbiddenword(FORBIDDENWORD) // forbidden word signing flag
+  , numaliasf(0)
+  , aliasf(NULL)
+  , aliasflen(0)
+  , numaliasm(0)
+  , aliasm(NULL)
 {
-  tablesize = 0;
-  tableptr = NULL;
-  flag_mode = FLAG_CHAR;
-  complexprefixes = 0;
-  utf8 = 0;
   langnum = 0;
   lang = NULL;
   enc = NULL;
   csconv = 0;
   ignorechars = NULL;
   ignorechars_utf16 = NULL;
   ignorechars_utf16_len = 0;
-  numaliasf = 0;
-  aliasf = NULL;
-  numaliasm = 0;
-  aliasm = NULL;
-  forbiddenword = FORBIDDENWORD; // forbidden word signing flag
   load_config(apath, key);
   int ec = load_tables(tpath, key);
   if (ec) {
     /* error condition - what should we do here */
     HUNSPELL_WARNING(stderr, "Hash Manager Error : %d\n",ec);
     if (tableptr) {
       free(tableptr);
       tableptr = NULL;
@@ -165,17 +114,17 @@ struct hentry * HashMgr::lookup(const ch
     return NULL;
 }
 
 // add a word to the hash table (private)
 int HashMgr::add_word(const char * word, int wbl, int wcl, unsigned short * aff,
     int al, const char * desc, bool onlyupcase)
 {
     bool upcasehomonym = false;
-    int descl = desc ? (aliasm ? sizeof(short) : strlen(desc) + 1) : 0;
+    int descl = desc ? (aliasm ? sizeof(char *) : strlen(desc) + 1) : 0;
     // variable-length hash record with word and optional fields
     struct hentry* hp = 
 	(struct hentry *) malloc (sizeof(struct hentry) + wbl + descl);
     if (!hp) return 1;
     char * hpw = hp->word;
     strcpy(hpw, word);
     if (ignorechars != NULL) {
       if (utf8) {
@@ -259,40 +208,43 @@ int HashMgr::add_word(const char * word,
     	    // remove hidden onlyupcase homonym
     	    if (hp->astr) free(hp->astr);
     	    free(hp);
        }
     return 0;
 }     
 
 int HashMgr::add_hidden_capitalized_word(char * word, int wbl, int wcl,
-    unsigned short * flags, int al, char * dp, int captype)
+    unsigned short * flags, int flagslen, char * dp, int captype)
 {
+    if (flags == NULL)
+        flagslen = 0;
+
     // add inner capitalized forms to handle the following allcap forms:
     // Mixed caps: OpenOffice.org -> OPENOFFICE.ORG
     // Allcaps with suffixes: CIA's -> CIA'S    
     if (((captype == HUHCAP) || (captype == HUHINITCAP) ||
-      ((captype == ALLCAP) && (flags != NULL))) &&
-      !((flags != NULL) && TESTAFF(flags, forbiddenword, al))) {
-          unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (al+1));
+      ((captype == ALLCAP) && (flagslen != 0))) &&
+      !((flagslen != 0) && TESTAFF(flags, forbiddenword, flagslen))) {
+          unsigned short * flags2 = (unsigned short *) malloc (sizeof(unsigned short) * (flagslen+1));
 	  if (!flags2) return 1;
-          if (al) memcpy(flags2, flags, al * sizeof(unsigned short));
-          flags2[al] = ONLYUPCASEFLAG;
+          if (flagslen) memcpy(flags2, flags, flagslen * sizeof(unsigned short));
+          flags2[flagslen] = ONLYUPCASEFLAG;
           if (utf8) {
               char st[BUFSIZE];
               w_char w[BUFSIZE];
               int wlen = u8_u16(w, BUFSIZE, word);
               mkallsmall_utf(w, wlen, langnum);
               mkallcap_utf(w, 1, langnum);
               u16_u8(st, BUFSIZE, w, wlen);
-              return add_word(st,wbl,wcl,flags2,al+1,dp, true);
+              return add_word(st,wbl,wcl,flags2,flagslen+1,dp, true);
            } else {
                mkallsmall(word, csconv);
                mkinitcap(word, csconv);
-               return add_word(word,wbl,wcl,flags2,al+1,dp, true);
+               return add_word(word,wbl,wcl,flags2,flagslen+1,dp, true);
            }
     }
     return 0;
 }
 
 // detect captype and modify word length for UTF-8 encoding
 int HashMgr::get_clen_and_captype(const char * word, int wbl, int * captype) {
     int len;
@@ -412,54 +364,56 @@ int HashMgr::load_tables(const char * tp
   unsigned short * flags;
   char * ts;
 
   // open dictionary file
   FileMgr * dict = new FileMgr(tpath, key);
   if (dict == NULL) return 1;
 
   // first read the first line of file to get hash table size */
-  if (!(ts = dict->getline())) {
-    HUNSPELL_WARNING(stderr, "error: empty dic file\n");
+  if ((ts = dict->getline()) == NULL) {
+    HUNSPELL_WARNING(stderr, "error: empty dic file %s\n", tpath);
     delete dict;
     return 2;
   }
   mychomp(ts);
 
   /* remove byte order mark */
   if (strncmp(ts,"\xEF\xBB\xBF",3) == 0) {
     memmove(ts, ts+3, strlen(ts+3)+1);
     // warning: dic file begins with byte order mark: possible incompatibility with old Hunspell versions
   }
 
   tablesize = atoi(ts);
-  if (tablesize == 0) {
+
+  int nExtra = 5 + USERWORD;
+
+  if (tablesize <= 0 || (tablesize >= (std::numeric_limits<int>::max() - 1 - nExtra) / int(sizeof(struct hentry *)))) {
     HUNSPELL_WARNING(stderr, "error: line 1: missing or bad word count in the dic file\n");
     delete dict;
     return 4;
   }
-  tablesize = tablesize + 5 + USERWORD;
-  if ((tablesize %2) == 0) tablesize++;
+  tablesize += nExtra;
+  if ((tablesize % 2) == 0) tablesize++;
 
   // allocate the hash table
-  tableptr = (struct hentry **) malloc(tablesize * sizeof(struct hentry *));
+  tableptr = (struct hentry **) calloc(tablesize, sizeof(struct hentry *));
   if (! tableptr) {
     delete dict;
     return 3;
   }
-  for (int i=0; i<tablesize; i++) tableptr[i] = NULL;
 
   // loop through all words on much list and add to hash
   // table and create word and affix strings
 
-  while ((ts = dict->getline())) {
+  while ((ts = dict->getline()) != NULL) {
     mychomp(ts);
     // split each line into word and morphological description
     dp = ts;
-    while ((dp = strchr(dp, ':'))) {
+    while ((dp = strchr(dp, ':')) != NULL) {
 	if ((dp > ts + 3) && (*(dp - 3) == ' ' || *(dp - 3) == '\t')) {
 	    for (dp -= 4; dp >= ts && (*dp == ' ' || *dp == '\t'); dp--);
 	    if (dp < ts) { // missing word
 		dp = NULL;
 	    } else {
 		*(dp + 1) = '\0';
 		dp = dp + 2;
 	    }
@@ -665,17 +619,17 @@ int  HashMgr::load_config(const char * a
   if (!afflst) {
     HUNSPELL_WARNING(stderr, "Error - could not open affix description file %s\n",affpath);
     return 1;
   }
 
     // read in each line ignoring any that do not
     // start with a known line type indicator
 
-    while ((line = afflst->getline())) {
+    while ((line = afflst->getline()) != NULL) {
         mychomp(line);
 
        /* remove byte order mark */
        if (firstline) {
          firstline = 0;
          if (strncmp(line,"\xEF\xBB\xBF",3) == 0) memmove(line, line+3, strlen(line+3)+1);
        }
 
@@ -805,17 +759,17 @@ int  HashMgr::parse_aliasf(char * line, 
       aliasflen = NULL;
       HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum());
       return 1;
    } 
  
    /* now parse the numaliasf lines to read in the remainder of the table */
    char * nl;
    for (int j=0; j < numaliasf; j++) {
-        if (!(nl = af->getline())) return 1;
+        if ((nl = af->getline()) == NULL) return 1;
         mychomp(nl);
         tp = nl;
         i = 0;
         aliasf[j] = NULL;
         aliasflen[j] = 0;
         piece = mystrsep(&tp, 0);
         while (piece) {
            if (*piece != '\0') {
@@ -912,17 +866,17 @@ int  HashMgr::parse_aliasm(char * line, 
       aliasm = NULL;
       HUNSPELL_WARNING(stderr, "error: line %d: missing data\n", af->getlinenum());
       return 1;
    } 
 
    /* now parse the numaliasm lines to read in the remainder of the table */
    char * nl = line;
    for (int j=0; j < numaliasm; j++) {
-        if (!(nl = af->getline())) return 1;
+        if ((nl = af->getline()) == NULL) return 1;
         mychomp(nl);
         tp = nl;
         i = 0;
         aliasm[j] = NULL;
         piece = mystrsep(&tp, ' ');
         while (piece) {
            if (*piece != '\0') {
                switch(i) {
--- a/extensions/spellcheck/hunspell/src/hashmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/hashmgr.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _HASHMGR_HXX_
 #define _HASHMGR_HXX_
 
 #include "hunvisapi.h"
 
 #include <stdio.h>
 
 #include "htypes.hxx"
--- a/extensions/spellcheck/hunspell/src/htypes.hxx
+++ b/extensions/spellcheck/hunspell/src/htypes.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _HTYPES_HXX_
 #define _HTYPES_HXX_
 
 #define ROTATE_LEN   5
 
 #define ROTATE(v,q) \
    (v) = ((v) << (q)) | (((v) >> (32 - q)) & ((1 << (q))-1));
 
--- a/extensions/spellcheck/hunspell/src/hunspell.cxx
+++ b/extensions/spellcheck/hunspell/src/hunspell.cxx
@@ -1,76 +1,24 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "hunspell.hxx"
 #include "hunspell.h"
 #ifndef MOZILLA_CLIENT
 #    include "config.h"
 #endif
 #include "csutil.hxx"
 
+#include <string>
+
 Hunspell::Hunspell(const char * affpath, const char * dpath, const char * key)
 {
     encoding = NULL;
     csconv = NULL;
     utf8 = 0;
     complexprefixes = 0;
     affixpath = mystrdup(affpath);
     maxdic = 0;
@@ -377,16 +325,20 @@ int Hunspell::insert_sug(char ***slst, c
 int Hunspell::spell(const char * word, int * info, char ** root)
 {
   struct hentry * rv=NULL;
   // need larger vector. For example, Turkish capital letter I converted a
   // 2-byte UTF-8 character (dotless i) by mkallsmall.
   char cw[MAXWORDUTF8LEN];
   char wspace[MAXWORDUTF8LEN];
   w_char unicw[MAXWORDLEN];
+
+  int info2 = 0;
+  if (!info) info = &info2; else *info = 0;
+
   // Hunspell supports XML input of the simplified API (see manual)
   if (strcmp(word, SPELL_XML) == 0) return 1;
   int nc = strlen(word);
   int wl2 = 0;
   if (utf8) {
     if (nc >= MAXWORDUTF8LEN) return 0;
   } else {
     if (nc >= MAXWORDLEN) return 0;
@@ -395,17 +347,16 @@ int Hunspell::spell(const char * word, i
   int abbv = 0;
   int wl = 0;
 
   // input conversion
   RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
   if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
   else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
 
-  int info2 = 0;
   if (wl == 0 || maxdic == 0) return 1;
   if (root) *root = NULL;
 
   // allow numbers with dots, dashes and commas (but forbid double separators: "..", "--" etc.)
   enum { NBEGIN, NNUM, NSEP };
   int nstate = NBEGIN;
   int i;
 
@@ -413,32 +364,32 @@ int Hunspell::spell(const char * word, i
     if ((cw[i] <= '9') && (cw[i] >= '0')) {
         nstate = NNUM;
     } else if ((cw[i] == ',') || (cw[i] == '.') || (cw[i] == '-')) {
         if ((nstate == NSEP) || (i == 0)) break;
         nstate = NSEP;
     } else break;
   }
   if ((i == wl) && (nstate == NNUM)) return 1;
-  if (!info) info = &info2; else *info = 0;
 
   switch(captype) {
      case HUHCAP:
+            /* FALLTHROUGH */
      case HUHINITCAP:
             *info += SPELL_ORIGCAP;
-     case NOCAP: {
+            /* FALLTHROUGH */
+     case NOCAP:
             rv = checkword(cw, info, root);
             if ((abbv) && !(rv)) {
                 memcpy(wspace,cw,wl);
                 *(wspace+wl) = '.';
                 *(wspace+wl+1) = '\0';
                 rv = checkword(wspace, info, root);
             }
             break;
-         }
      case ALLCAP: {
             *info += SPELL_ORIGCAP;
             rv = checkword(cw, info, root);
             if (rv) break;
             if (abbv) {
                 memcpy(wspace,cw,wl);
                 *(wspace+wl) = '.';
                 *(wspace+wl+1) = '\0';
@@ -452,17 +403,17 @@ int Hunspell::spell(const char * word, i
         	//There are no really sane circumstances where this could fail,
         	//but anyway...
         	if (char * apostrophe = strchr(cw, '\'')) {
                     if (utf8) {
             	        w_char tmpword[MAXWORDLEN];
             	        *apostrophe = '\0';
             	        wl2 = u8_u16(tmpword, MAXWORDLEN, cw);
             	        *apostrophe = '\'';
-		        if (wl2 < nc) {
+		        if (wl2 >= 0 && wl2 < nc) {
 		            mkinitcap2(apostrophe + 1, unicw + wl2 + 1, nc - wl2 - 1);
 			    rv = checkword(cw, info, root);
 			    if (rv) break;
 		        }
                     } else {
 		        mkinitcap2(apostrophe + 1, unicw, nc);
 		        rv = checkword(cw, info, root);
 		        if (rv) break;
@@ -799,29 +750,38 @@ int Hunspell::suggest(char*** slst, cons
      case HUHCAP: {
                      ns = pSMgr->suggest(slst, cw, ns, &onlycmpdsug);
                      if (ns != -1) {
                         int prevns;
     		        // something.The -> something. The
                         char * dot = strchr(cw, '.');
 		        if (dot && (dot > cw)) {
 		            int captype_;
-		            if (utf8) {
+		            if (utf8)
+                            {
 		               w_char w_[MAXWORDLEN];
 			       int wl_ = u8_u16(w_, MAXWORDLEN, dot + 1);
 		               captype_ = get_captype_utf8(w_, wl_, langnum);
 		            } else captype_ = get_captype(dot+1, strlen(dot+1), csconv);
-		    	    if (captype_ == INITCAP) {
+		    	    if (captype_ == INITCAP)
+                            {
                         	char * st = mystrdup(cw);
-                        	if (st) st = (char *) realloc(st, wl + 2);
-				if (st) {
-                        		st[(dot - cw) + 1] = ' ';
-                        		strcpy(st + (dot - cw) + 2, dot + 1);
-                    			ns = insert_sug(slst, st, ns);
-					free(st);
+                        	if (st)
+                        	{
+                                    char *newst = (char *) realloc(st, wl + 2);
+                                    if (newst == NULL)
+                                        free(st);
+                                    st = newst;
+                        	}
+				if (st)
+                                {
+                        	    st[(dot - cw) + 1] = ' ';
+                        	    strcpy(st + (dot - cw) + 2, dot + 1);
+                    		    ns = insert_sug(slst, st, ns);
+				    free(st);
 				}
 		    	    }
 		        }
                         if (captype == HUHINITCAP) {
                             // TheOpenOffice.org -> The OpenOffice.org
                             memcpy(wspace,cw,(wl+1));
                             mkinitsmall2(wspace, unicw, nc);
                             ns = pSMgr->suggest(slst, wspace, ns, &onlycmpdsug);
@@ -897,17 +857,17 @@ int Hunspell::suggest(char*** slst, cons
       for (int j=0; j < ns; j++) {
           char * pos = strchr((*slst)[j],'-');
           if (pos) {
               int info;
               char w[MAXWORDUTF8LEN];
               *pos = '\0';
               strcpy(w, (*slst)[j]);
               strcat(w, pos + 1);
-              spell(w, &info, NULL);
+              (void)spell(w, &info, NULL);
               if ((info & SPELL_COMPOUND) && (info & SPELL_FORBIDDEN)) {
                   *pos = ' ';
               } else *pos = '-';
           }
       }
   }
   // END OF LANG_hu section
 
@@ -1719,16 +1679,23 @@ int Hunspell::get_xml_par(char * dest, c
    return (int)(d - dest);
 }
 
 int Hunspell::get_langnum() const
 {
    return langnum;
 }
 
+int Hunspell::input_conv(const char * word, char * dest)
+{
+  RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
+  return (rl && rl->conv(word, dest));
+}
+
+
 // return the beginning of the element (attr == NULL) or the attribute
 const char * Hunspell::get_xml_pos(const char * s, const char * attr)
 {
   const char * end = strchr(s, '>');
   const char * p = s;
   if (attr == NULL) return end;
   do {
     p = strstr(p, attr);
@@ -1743,78 +1710,91 @@ int Hunspell::check_xml_par(const char *
     strcmp(cw, value) == 0) return 1;
   return 0;
 }
 
 int Hunspell::get_xml_list(char ***slst, char * list, const char * tag) {
     int n = 0;
     char * p;
     if (!list) return 0;
-    for (p = list; (p = strstr(p, tag)); p++) n++;
+    for (p = list; ((p = strstr(p, tag)) != NULL); p++) n++;
     if (n == 0) return 0;
     *slst = (char **) malloc(sizeof(char *) * n);
     if (!*slst) return 0;
-    for (p = list, n = 0; (p = strstr(p, tag)); p++, n++) {
+    for (p = list, n = 0; ((p = strstr(p, tag)) != NULL); p++, n++) {
         int l = strlen(p);
         (*slst)[n] = (char *) malloc(l + 1);
         if (!(*slst)[n]) return n;
         if (!get_xml_par((*slst)[n], p + strlen(tag) - 1, l)) {
             free((*slst)[n]);
             break;
         }
     }
     return n;
 }
 
+namespace
+{
+    void myrep(std::string& str, const std::string& search, const std::string& replace)
+    {
+        size_t pos = 0;
+        while ((pos = str.find(search, pos)) != std::string::npos)
+        {
+           str.replace(pos, search.length(), replace);
+           pos += replace.length();
+        }
+    }
+}
+
 int Hunspell::spellml(char*** slst, const char * word)
 {
   char *q, *q2;
   char cw[MAXWORDUTF8LEN], cw2[MAXWORDUTF8LEN];
   q = (char *) strstr(word, "<query");
   if (!q) return 0; // bad XML input
   q2 = strchr(q, '>');
   if (!q2) return 0; // bad XML input
   q2 = strstr(q2, "<word");
   if (!q2) return 0; // bad XML input
   if (check_xml_par(q, "type=", "analyze")) {
-      int n = 0, s = 0;
+      int n = 0;
       if (get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN - 10)) n = analyze(slst, cw);
       if (n == 0) return 0;
       // convert the result to <code><a>ana1</a><a>ana2</a></code> format
-      for (int i = 0; i < n; i++) s+= strlen((*slst)[i]);
-      char * r = (char *) malloc(6 + 5 * s + 7 * n + 7 + 1); // XXX 5*s->&->&amp;
-      if (!r) return 0;
-      strcpy(r, "<code>");
+      std::string r;
+      r.append("<code>");
       for (int i = 0; i < n; i++) {
-        int l = strlen(r);
-        strcpy(r + l, "<a>");
-        strcpy(r + l + 3, (*slst)[i]);
-        mystrrep(r + l + 3, "\t", " ");
-        mystrrep(r + l + 3, "<", "&lt;");
-        mystrrep(r + l + 3, "&", "&amp;");
-        strcat(r, "</a>");
+        r.append("<a>");
+
+        std::string entry((*slst)[i]);
         free((*slst)[i]);
+        myrep(entry, "\t", " ");
+        myrep(entry, "&", "&amp;");
+        myrep(entry, "<", "&lt;");
+        r.append(entry);
+
+        r.append("</a>");
       }
-      strcat(r, "</code>");
-      (*slst)[0] = r;
+      r.append("</code>");
+      (*slst)[0] = mystrdup(r.c_str());
       return 1;
   } else if (check_xml_par(q, "type=", "stem")) {
       if (get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN - 1)) return stem(slst, cw);
   } else if (check_xml_par(q, "type=", "generate")) {
       int n = get_xml_par(cw, strchr(q2, '>'), MAXWORDUTF8LEN - 1);
       if (n == 0) return 0;
       char * q3 = strstr(q2 + 1, "<word");
       if (q3) {
         if (get_xml_par(cw2, strchr(q3, '>'), MAXWORDUTF8LEN - 1)) {
             return generate(slst, cw, cw2);
         }
       } else {
-        if ((q2 = strstr(q2 + 1, "<code"))) {
+        if ((q2 = strstr(q2 + 1, "<code")) != NULL) {
           char ** slst2;
-          if ((n = get_xml_list(&slst2, strchr(q2, '>'), "<a>"))) {
+          if ((n = get_xml_list(&slst2, strchr(q2, '>'), "<a>")) != 0) {
             int n2 = generate(slst, cw, slst2, n);
             freelist(&slst2, n);
             return uniqlist(*slst, n2);
           }
           freelist(&slst2, n);
         }
       }
   }
--- a/extensions/spellcheck/hunspell/src/hunspell.h
+++ b/extensions/spellcheck/hunspell/src/hunspell.h
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _MYSPELLMGR_H_
 #define _MYSPELLMGR_H_
 
 #include "hunvisapi.h"
 
 #ifdef __cplusplus
 extern "C" {
 #endif
--- a/extensions/spellcheck/hunspell/src/hunspell.hxx
+++ b/extensions/spellcheck/hunspell/src/hunspell.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #include "hunvisapi.h"
 
 #include "hashmgr.hxx"
 #include "affixmgr.hxx"
 #include "suggestmgr.hxx"
 #include "langnum.hxx"
 
 #define  SPELL_XML "<?xml?>"
@@ -71,32 +14,41 @@
 #define HUNSPELL_OK       (1 << 0)
 #define HUNSPELL_OK_WARN  (1 << 1)
 
 #ifndef _MYSPELLMGR_HXX_
 #define _MYSPELLMGR_HXX_
 
 class LIBHUNSPELL_DLL_EXPORTED Hunspell
 {
+private:
+  Hunspell(const Hunspell&);
+  Hunspell& operator = (const Hunspell&);
+private:
   AffixMgr*       pAMgr;
   HashMgr*        pHMgr[MAXDIC];
   int             maxdic;
   SuggestMgr*     pSMgr;
   char *          affixpath;
   char *          encoding;
   struct cs_info * csconv;
   int             langnum;
   int             utf8;
   int             complexprefixes;
   char**          wordbreak;
 
 public:
 
   /* Hunspell(aff, dic) - constructor of Hunspell class
    * input: path of affix file and dictionary file
+   *
+   * In WIN32 environment, use UTF-8 encoded paths started with the long path
+   * prefix \\\\?\\ to handle system-independent character encoding and very
+   * long path names (without the long path prefix Hunspell will use fopen()
+   * with system-dependent character encoding instead of _wfopen()).
    */
 
   Hunspell(const char * affpath, const char * dpath, const char * key = NULL);
   ~Hunspell();
 
   /* load extra dictionaries (only dic files) */
   int add_dic(const char * dpath, const char * key = NULL);
 
@@ -183,16 +135,19 @@ public:
   /* get extra word characters definied in affix file for tokenization */
   const char * get_wordchars();
   unsigned short * get_wordchars_utf16(int * len);
 
   struct cs_info * get_csconv();
   const char * get_version();
 
   int get_langnum() const;
+
+  /* need for putdic */
+  int input_conv(const char * word, char * dest);
   
   /* experimental and deprecated functions */
 
 #ifdef HUNSPELL_EXPERIMENTAL
   /* suffix is an affix flag string, similarly in dictionary files */  
   int put_word_suffix(const char * word, const char * suffix);
   char * morph_with_correction(const char * word);
 
--- a/extensions/spellcheck/hunspell/src/hunvisapi.h
+++ b/extensions/spellcheck/hunspell/src/hunvisapi.h
@@ -1,51 +1,18 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code is Caolan McNamara.
- * Portions created by the Initial Developer are Copyright (C) 2010 the
- * Initial Developer. All Rights Reserved.
- * 
- * Contributor(s): Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _HUNSPELL_VISIBILITY_H_
 #define _HUNSPELL_VISIBILITY_H_
 
 #if defined(HUNSPELL_STATIC)
 #  define LIBHUNSPELL_DLL_EXPORTED
 #elif defined(_MSC_VER)
 #  if defined(BUILDING_LIBHUNSPELL)
 #    define LIBHUNSPELL_DLL_EXPORTED __declspec(dllexport)
 #  else
 #    define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport)
 #  endif
-#elif BUILDING_LIBHUNSPELL && 1
+#elif defined(BUILDING_LIBHUNSPELL) && 1
 #  define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default")))
 #else
 #  define LIBHUNSPELL_DLL_EXPORTED
 #endif
 
 #endif
--- a/extensions/spellcheck/hunspell/src/hunzip.cxx
+++ b/extensions/spellcheck/hunspell/src/hunzip.cxx
@@ -1,83 +1,52 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #include <stdlib.h> 
 #include <string.h>
 #include <stdio.h> 
 
 #include "hunzip.hxx"
+#include "csutil.hxx"
 
 #define CODELEN  65536
 #define BASEBITREC 5000
 
 #define UNCOMPRESSED '\002'
 #define MAGIC "hz0"
 #define MAGIC_ENCRYPT "hz1"
 #define MAGICLEN (sizeof(MAGIC) - 1)
 
 int Hunzip::fail(const char * err, const char * par) {
     fprintf(stderr, err, par);
     return -1;
 }
 
-Hunzip::Hunzip(const char * file, const char * key) {
-    bufsiz = 0;
-    lastbit = 0;
-    inc = 0;
-    outc = 0;
-    dec = NULL;
-    fin = NULL;
-    filename = (char *) malloc(strlen(file) + 1);
-    if (filename) strcpy(filename, file);
+Hunzip::Hunzip(const char * file, const char * key)
+    : fin(NULL)
+    , bufsiz(0)
+    , lastbit(0)
+    , inc(0)
+    , inbits(0)
+    , outc(0)
+    , dec(NULL)
+{
+    in[0] = out[0] = line[0] = '\0';
+    filename = mystrdup(file);
     if (getcode(key) == -1) bufsiz = -1;
     else bufsiz = getbuf();
 }
 
 int Hunzip::getcode(const char * key) {
     unsigned char c[2];
     int i, j, n, p;
     int allocatedbit = BASEBITREC;
     const char * enc = key;
 
     if (!filename) return -1;
 
-    fin = fopen(filename, "rb");
+    fin = myfopen(filename, "rb");
     if (!fin) return -1;
 
     // read magic number
     if ((fread(in, 1, 3, fin) < MAGICLEN)
         || !(strncmp(MAGIC, in, MAGICLEN) == 0 ||
                 strncmp(MAGIC_ENCRYPT, in, MAGICLEN) == 0)) {
             return fail(MSG_FORMAT, filename);
     }
--- a/extensions/spellcheck/hunspell/src/hunzip.hxx
+++ b/extensions/spellcheck/hunspell/src/hunzip.hxx
@@ -1,41 +1,10 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+/* hunzip: file decompression for sorted dictionaries with optional encryption,
+ * algorithm: prefix-suffix encoding and 16-bit Huffman encoding */
 
 #ifndef _HUNZIP_HXX_
 #define _HUNZIP_HXX_
 
 #include "hunvisapi.h"
 
 #include <stdio.h>
 
@@ -49,17 +18,19 @@
 
 struct bit {
     unsigned char c[2];
     int v[2];
 };
 
 class LIBHUNSPELL_DLL_EXPORTED Hunzip
 {
-
+private:
+    Hunzip(const Hunzip&);
+    Hunzip& operator = (const Hunzip&);
 protected:
     char * filename;
     FILE * fin;
     int bufsiz, lastbit, inc, inbits, outc;
     struct bit * dec;        // code table
     char in[BUFSIZE];        // input buffer
     char out[BUFSIZE + 1];   // Huffman-decoded buffer
     char line[BUFSIZE + 50]; // decoded line
--- a/extensions/spellcheck/hunspell/src/langnum.hxx
+++ b/extensions/spellcheck/hunspell/src/langnum.hxx
@@ -1,64 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _LANGNUM_HXX_
 #define _LANGNUM_HXX_
 
 /*
  language numbers for language specific codes
  see http://l10n.openoffice.org/languages.html
 */
 
new file mode 100644
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/license.hunspell
@@ -0,0 +1,61 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Hunspell, based on MySpell.
+ *
+ * The Initial Developers of the Original Code are
+ * Kevin Hendricks (MySpell) and Laszlo Nemeth (Hunspell).
+ * Portions created by the Initial Developers are Copyright (C) 2002-2005
+ * the Initial Developers. All Rights Reserved.
+ *
+ * Contributor(s):
+ * David Einstein 
+ * Davide Prina
+ * Giuseppe Modugno 
+ * Gianluca Turconi
+ * Simon Brouwer
+ * Noll Janos
+ * Biro Arpad
+ * Goldman Eleonora
+ * Sarlos Tamas
+ * Bencsath Boldizsar
+ * Halacsy Peter
+ * Dvornik Laszlo
+ * Gefferth Andras
+ * Nagy Viktor
+ * Varga Daniel
+ * Chris Halls
+ * Rene Engelhard
+ * Bram Moolenaar
+ * Dafydd Jones
+ * Harri Pitkanen
+ * Andras Timar
+ * Tor Lillqvist
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef MOZILLA_CLIENT
+#    include "config.h"
+#endif
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/01-675553.diff
@@ -0,0 +1,24 @@
+Bug 675553 - Switch from PRBool to bool.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5517,17 +5517,17 @@ struct cs_info * get_current_cs(const ch
+   if (NS_FAILED(rv))
+     return ccs;
+   decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+ 
+   if (NS_FAILED(rv))
+     return ccs;
+ 
+   for (unsigned int i = 0; i <= 0xff; ++i) {
+-    PRBool success = PR_FALSE;
++    bool success = false;
+     // We want to find the upper/lowercase equivalents of each byte
+     // in this 1-byte character encoding.  Call our encoding/decoding
+     // APIs separately for each byte since they may reject some of the
+     // bytes, and we want to handle errors separately for each byte.
+     char lower, upper;
+     do {
+       if (i == 0)
+         break;
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/02-690892.diff
@@ -0,0 +1,24 @@
+Bug 690892 - Replace PR_TRUE/PR_FALSE with true/false.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5549,17 +5549,17 @@ struct cs_info * get_current_cs(const ch
+ 
+       uniCased = ToUpperCase(uni);
+       rv = encoder->Convert(&uniCased, &uniLength, &upper, &charLength);
+       // Explicitly check NS_OK because we don't want to allow
+       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+       if (rv != NS_OK || charLength != 1 || uniLength != 1)
+         break;
+ 
+-      success = PR_TRUE;
++      success = true;
+     } while (0);
+ 
+     if (success) {
+       ccs[i].cupper = upper;
+       ccs[i].clower = lower;
+     } else {
+       ccs[i].cupper = i;
+       ccs[i].clower = i;
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/03-clang.diff
@@ -0,0 +1,25 @@
+Silence the warning about empty while body loop in clang.
+
+diff --git a/extensions/spellcheck/hunspell/src/affentry.cxx b/extensions/spellcheck/hunspell/src/affentry.cxx
+--- a/extensions/spellcheck/hunspell/src/affentry.cxx
++++ b/extensions/spellcheck/hunspell/src/affentry.cxx
+@@ -571,17 +571,18 @@ inline int SfxEntry::test_condition(cons
+                             while (p && *p != ']' && ((p = nextchar(p)) != NULL));
+ 			    st--;
+                         }
+                         if (p && *p != ']') p = nextchar(p);
+                     } else if (pos) {
+                         if (neg) return 0;
+                         else if (i == numconds) return 1;
+                         ingroup = true;
+-			while (p && *p != ']' && ((p = nextchar(p)) != NULL));
++			while (p && *p != ']' && ((p = nextchar(p)) != NULL))
++                           ;
+ //			if (p && *p != ']') p = nextchar(p);
+                         st--;
+                     }
+                     if (!pos) {
+                         i++;
+                         st--;
+                     }
+                     if (st < beg && p && *p != ']') return 0; // word <= condition
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/04-777292.diff
@@ -0,0 +1,24 @@
+Bug 777292 - Change nsnull to nullptr.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5507,17 +5507,17 @@ struct cs_info * get_current_cs(const ch
+   nsresult rv;
+   nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &rv);
+   if (NS_FAILED(rv))
+     return ccs;
+ 
+   rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder));
+   if (NS_FAILED(rv))
+     return ccs;
+-  encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nsnull, '?');
++  encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nullptr, '?');
+   rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder));
+   if (NS_FAILED(rv))
+     return ccs;
+   decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+ 
+   if (NS_FAILED(rv))
+     return ccs;
+ 
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/05-579517.diff
@@ -0,0 +1,24 @@
+Bug 579517 - Convert NSPR numeric types to stdint types.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5528,17 +5528,17 @@ struct cs_info * get_current_cs(const ch
+     // APIs separately for each byte since they may reject some of the
+     // bytes, and we want to handle errors separately for each byte.
+     char lower, upper;
+     do {
+       if (i == 0)
+         break;
+       const char source = char(i);
+       PRUnichar uni, uniCased;
+-      PRInt32 charLength = 1, uniLength = 1;
++      int32_t charLength = 1, uniLength = 1;
+ 
+       rv = decoder->Convert(&source, &charLength, &uni, &uniLength);
+       // Explicitly check NS_OK because we don't want to allow
+       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+       if (rv != NS_OK || charLength != 1 || uniLength != 1)
+         break;
+       uniCased = ToLowerCase(uni);
+       rv = encoder->Convert(&uniCased, &uniLength, &lower, &charLength);
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/06-784776.diff
@@ -0,0 +1,43 @@
+Bug 784776 - Don't assume NULL is numeric in Hunspell code.
+
+diff --git a/extensions/spellcheck/hunspell/src/affentry.hxx b/extensions/spellcheck/hunspell/src/affentry.hxx
+--- a/extensions/spellcheck/hunspell/src/affentry.hxx
++++ b/extensions/spellcheck/hunspell/src/affentry.hxx
+@@ -26,17 +26,17 @@ public:
+ 
+   PfxEntry(AffixMgr* pmgr, affentry* dp );
+   ~PfxEntry();
+ 
+   inline bool          allowCross() { return ((opts & aeXPRODUCT) != 0); }
+   struct hentry *      checkword(const char * word, int len, char in_compound, 
+                             const FLAG needflag = FLAG_NULL);
+ 
+-  struct hentry *      check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL);
++  struct hentry *      check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = FLAG_NULL);
+ 
+   char *      check_morph(const char * word, int len, char in_compound,
+                             const FLAG needflag = FLAG_NULL);
+ 
+   char *      check_twosfx_morph(const char * word, int len,
+                   char in_compound, const FLAG needflag = FLAG_NULL);
+ 
+   inline FLAG getFlag()   { return aflag;   }
+@@ -93,17 +93,17 @@ public:
+   ~SfxEntry();
+ 
+   inline bool          allowCross() { return ((opts & aeXPRODUCT) != 0); }
+   struct hentry *   checkword(const char * word, int len, int optflags, 
+                     PfxEntry* ppfx, char ** wlst, int maxSug, int * ns,
+ //                    const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT);
+                     const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0);
+ 
+-  struct hentry *   check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = NULL);
++  struct hentry *   check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
+ 
+   char *      check_twosfx_morph(const char * word, int len, int optflags,
+                  PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
+   struct hentry * get_next_homonym(struct hentry * he);
+   struct hentry * get_next_homonym(struct hentry * word, int optflags, PfxEntry* ppfx, 
+     const FLAG cclass, const FLAG needflag);
+ 
+ 
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/07-927728.diff
@@ -0,0 +1,62 @@
+Bug 927728 - Replace PRUnichar with char16_t.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -5527,17 +5527,17 @@ struct cs_info * get_current_cs(const ch
+     // in this 1-byte character encoding.  Call our encoding/decoding
+     // APIs separately for each byte since they may reject some of the
+     // bytes, and we want to handle errors separately for each byte.
+     char lower, upper;
+     do {
+       if (i == 0)
+         break;
+       const char source = char(i);
+-      PRUnichar uni, uniCased;
++      char16_t uni, uniCased;
+       int32_t charLength = 1, uniLength = 1;
+ 
+       rv = decoder->Convert(&source, &charLength, &uni, &uniLength);
+       // Explicitly check NS_OK because we don't want to allow
+       // NS_OK_UDEC_MOREOUTPUT or NS_OK_UDEC_MOREINPUT.
+       if (rv != NS_OK || charLength != 1 || uniLength != 1)
+         break;
+       uniCased = ToLowerCase(uni);
+@@ -5680,17 +5680,17 @@ unsigned short unicodetoupper(unsigned s
+   // There are a dotless lower case i pair of upper `I',
+   // and an upper I with dot pair of lower `i'. 
+   if (c == 0x0069 && ((langnum == LANG_az) || (langnum == LANG_tr)))
+     return 0x0130;
+ #ifdef OPENOFFICEORG
+   return static_cast<unsigned short>(u_toupper(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+-  return ToUpperCase((PRUnichar) c);
++  return ToUpperCase((char16_t) c);
+ #else
+   return (utf_tbl) ? utf_tbl[c].cupper : c;
+ #endif
+ #endif
+ }
+ 
+ unsigned short unicodetolower(unsigned short c, int langnum)
+ {
+@@ -5698,17 +5698,17 @@ unsigned short unicodetolower(unsigned s
+   // There are a dotless lower case i pair of upper `I',
+   // and an upper I with dot pair of lower `i'. 
+   if (c == 0x0049 && ((langnum == LANG_az) || (langnum == LANG_tr)))
+     return 0x0131;
+ #ifdef OPENOFFICEORG
+   return static_cast<unsigned short>(u_tolower(c));
+ #else
+ #ifdef MOZILLA_CLIENT
+-  return ToLowerCase((PRUnichar) c);
++  return ToLowerCase((char16_t) c);
+ #else
+   return (utf_tbl) ? utf_tbl[c].clower : c;
+ #endif
+ #endif
+ }
+ 
+ int unicodeisalpha(unsigned short c)
+ {
new file mode 100755
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/08-943268.diff
@@ -0,0 +1,71 @@
+Bug 943268 - Remove nsCharsetAlias and nsCharsetConverterManager.
+
+diff --git a/extensions/spellcheck/hunspell/src/csutil.cxx b/extensions/spellcheck/hunspell/src/csutil.cxx
+--- a/extensions/spellcheck/hunspell/src/csutil.cxx
++++ b/extensions/spellcheck/hunspell/src/csutil.cxx
+@@ -28,23 +28,22 @@ struct unicode_info {
+ #  ifndef MOZILLA_CLIENT
+ #    include "utf_info.cxx"
+ #    define UTF_LST_LEN (sizeof(utf_lst) / (sizeof(unicode_info)))
+ #  endif
+ #endif
+ 
+ #ifdef MOZILLA_CLIENT
+ #include "nsCOMPtr.h"
+-#include "nsServiceManagerUtils.h"
+ #include "nsIUnicodeEncoder.h"
+ #include "nsIUnicodeDecoder.h"
+ #include "nsUnicharUtils.h"
+-#include "nsICharsetConverterManager.h"
++#include "mozilla/dom/EncodingUtils.h"
+ 
+-static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID);
++using mozilla::dom::EncodingUtils;
+ #endif
+ 
+ struct unicode_info2 {
+   char cletter;
+   unsigned short cupper;
+   unsigned short clower;
+ };
+ 
+@@ -5500,32 +5499,27 @@ struct cs_info * get_current_cs(const ch
+     ccs[i].cupper = i;
+   }
+ 
+ 
+   nsCOMPtr<nsIUnicodeEncoder> encoder; 
+   nsCOMPtr<nsIUnicodeDecoder> decoder; 
+ 
+   nsresult rv;
+-  nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &rv);
+-  if (NS_FAILED(rv))
++
++  nsAutoCString label(es);
++  nsAutoCString encoding;
++  if (!EncodingUtils::FindEncodingForLabelNoReplacement(label, encoding)) {
+     return ccs;
+-
+-  rv = ccm->GetUnicodeEncoder(es, getter_AddRefs(encoder));
+-  if (NS_FAILED(rv))
+-    return ccs;
++  }
++  encoder = EncodingUtils::EncoderForEncoding(encoding);
++  decoder = EncodingUtils::DecoderForEncoding(encoding);
+   encoder->SetOutputErrorBehavior(encoder->kOnError_Signal, nullptr, '?');
+-  rv = ccm->GetUnicodeDecoder(es, getter_AddRefs(decoder));
+-  if (NS_FAILED(rv))
+-    return ccs;
+   decoder->SetInputErrorBehavior(decoder->kOnError_Signal);
+ 
+-  if (NS_FAILED(rv))
+-    return ccs;
+-
+   for (unsigned int i = 0; i <= 0xff; ++i) {
+     bool success = false;
+     // We want to find the upper/lowercase equivalents of each byte
+     // in this 1-byte character encoding.  Call our encoding/decoding
+     // APIs separately for each byte since they may reject some of the
+     // bytes, and we want to handle errors separately for each byte.
+     char lower, upper;
+     do {
new file mode 100644
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/09-license.diff
@@ -0,0 +1,18 @@
+Don't include config.h in license.hunspell if MOZILLA_CLIENT is set.
+
+diff --git a/extensions/spellcheck/hunspell/src/license.hunspell b/extensions/spellcheck/hunspell/src/license.hunspell
+--- a/extensions/spellcheck/hunspell/src/license.hunspell
++++ b/extensions/spellcheck/hunspell/src/license.hunspell
+@@ -51,9 +51,11 @@
+  * use your version of this file under the terms of the MPL, indicate your
+  * decision by deleting the provisions above and replace them with the notice
+  * and other provisions required by the GPL or the LGPL. If you do not delete
+  * the provisions above, a recipient may use your version of this file under
+  * the terms of any one of the MPL, the GPL or the LGPL.
+  *
+  * ***** END LICENSE BLOCK ***** */
+ 
+-#include "config.h"
++#ifndef MOZILLA_CLIENT
++#    include "config.h"
++#endif
--- a/extensions/spellcheck/hunspell/src/phonet.cxx
+++ b/extensions/spellcheck/hunspell/src/phonet.cxx
@@ -1,53 +1,36 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developer of the Original Code is Bjrn Jacke. Portions created
- * by the Initial Developers are Copyright (C) 2000-2007 the Initial
- * Developers. All Rights Reserved.
- * 
- * Contributor(s): Bjrn Jacke (bjoern.jacke@gmx.de)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * Changelog:
- *  2000-01-05  Bjrn Jacke <bjoern.jacke AT gmx.de>
- *              Initial Release insprired by the article about phonetic
- *              transformations out of c't 25/1999
- *
- *  2007-07-26  Bjrn Jacke <bjoern.jacke AT gmx.de>
- *              Released under MPL/GPL/LGPL tri-license for Hunspell
- *
- *  2007-08-23  Lszl Nmeth <nemeth at OOo>
- *              Porting from Aspell to Hunspell using C-like structs
- *
- ******* END LICENSE BLOCK *******/
+/*  phonetic.c - generic replacement aglogithms for phonetic transformation
+    Copyright (C) 2000 Bjoern Jacke
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License version 2.1 as published by the Free Software Foundation;
+ 
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; If not, see
+    <http://www.gnu.org/licenses/>.
+
+    Changelog:
+
+    2000-01-05  Bjoern Jacke <bjoern at j3e.de>
+                Initial Release insprired by the article about phonetic
+                transformations out of c't 25/1999
+
+    2007-07-26  Bjoern Jacke <bjoern at j3e.de>
+		Released under MPL/GPL/LGPL tri-license for Hunspell
+		
+    2007-08-23  Laszlo Nemeth <nemeth at OOo>
+                Porting from Aspell to Hunspell using C-like structs
+*/
 
 #include <stdlib.h> 
 #include <string.h>
 #include <stdio.h> 
 #include <ctype.h>
 
 #include "csutil.hxx"
 #include "phonet.hxx"
@@ -99,17 +82,18 @@ int phonet (const char * inword, char * 
     int  i,j,k=0,n,p,z;
     int  k0,n0,p0=-333,z0;
     char c, c0;
     const char * s;
     typedef unsigned char uchar;    
     char word[MAXPHONETUTF8LEN + 1];
     if (len == -1) len = strlen(inword);
     if (len > MAXPHONETUTF8LEN) return 0;
-    strcpy(word, inword);
+    strncpy(word, inword, MAXPHONETUTF8LEN);
+    word[MAXPHONETUTF8LEN] = '\0';
   
     /**  check word  **/
     i = j = z = 0;
     while ((c = word[i]) != '\0') {
       n = parms.hash[(uchar) c];
       z0 = 0;
 
       if (n >= 0) {
--- a/extensions/spellcheck/hunspell/src/phonet.hxx
+++ b/extensions/spellcheck/hunspell/src/phonet.hxx
@@ -1,53 +1,36 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developer of the Original Code is Bjrn Jacke. Portions created
- * by the Initial Developers are Copyright (C) 2000-2007 the Initial
- * Developers. All Rights Reserved.
- * 
- * Contributor(s): Bjrn Jacke (bjoern.jacke@gmx.de)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * Changelog:
- *  2000-01-05  Bjrn Jacke <bjoern.jacke AT gmx.de>
- *              Initial Release insprired by the article about phonetic
- *              transformations out of c't 25/1999
- *
- *  2007-07-20  Bjrn Jacke <bjoern.jacke AT gmx.de>
- *              Released under MPL/GPL/LGPL tri-license for Hunspell
- *
- *  2007-08-22  Lszl Nmeth <nemeth at OOo>
- *              Porting from Aspell to Hunspell by little modifications
- *
- ******* END LICENSE BLOCK *******/
+/*  phonetic.c - generic replacement aglogithms for phonetic transformation
+    Copyright (C) 2000 Bjoern Jacke
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License version 2.1 as published by the Free Software Foundation;
+ 
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+ 
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; If not, see
+    <http://www.gnu.org/licenses/>.
+
+    Changelog:
+
+    2000-01-05  Bjoern Jacke <bjoern at j3e.de>
+                Initial Release insprired by the article about phonetic
+                transformations out of c't 25/1999
+
+    2007-07-26  Bjoern Jacke <bjoern at j3e.de>
+		Released under MPL/GPL/LGPL tri-license for Hunspell
+		
+    2007-08-23  Laszlo Nemeth <nemeth at OOo>
+                Porting from Aspell to Hunspell using C-like structs
+*/
 
 #ifndef __PHONETHXX__
 #define __PHONETHXX__
 
 #define HASHSIZE          256
 #define MAXPHONETLEN      256
 #define MAXPHONETUTF8LEN  (MAXPHONETLEN * 4)
 
--- a/extensions/spellcheck/hunspell/src/replist.cxx
+++ b/extensions/spellcheck/hunspell/src/replist.cxx
@@ -1,41 +1,10 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "replist.hxx"
 #include "csutil.hxx"
 
--- a/extensions/spellcheck/hunspell/src/replist.hxx
+++ b/extensions/spellcheck/hunspell/src/replist.hxx
@@ -1,52 +1,21 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 /* string replacement list class */
 #ifndef _REPLIST_HXX_
 #define _REPLIST_HXX_
 
 #include "hunvisapi.h"
 
 #include "w_char.hxx"
 
 class LIBHUNSPELL_DLL_EXPORTED RepList
 {
+private:
+    RepList(const RepList&);
+    RepList& operator = (const RepList&);
 protected:
     replentry ** dat;
     int size;
     int pos;
 
 public:
     RepList(int n);
     ~RepList();
--- a/extensions/spellcheck/hunspell/src/suggestmgr.cxx
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.cxx
@@ -1,64 +1,10 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
+#include "license.hunspell"
+#include "license.myspell"
 
 #include <stdlib.h> 
 #include <string.h>
 #include <stdio.h> 
 #include <ctype.h>
 
 #include "suggestmgr.hxx"
 #include "htypes.hxx"
@@ -156,17 +102,20 @@ SuggestMgr::~SuggestMgr()
 #endif
 }
 
 int SuggestMgr::testsug(char** wlst, const char * candidate, int wl, int ns, int cpdsuggest,
    int * timer, clock_t * timelimit) {
       int cwrd = 1;
       if (ns == maxSug) return maxSug;
       for (int k=0; k < ns; k++) {
-        if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+        if (strcmp(candidate,wlst[k]) == 0) {
+            cwrd = 0;
+            break;
+        }
       }
       if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) {
         wlst[ns] = mystrdup(candidate);
         if (wlst[ns] == NULL) {
             for (int j=0; j<ns; j++) free(wlst[j]);
             return -1;
         }
         ns++;
@@ -413,18 +362,22 @@ int SuggestMgr::mapchars(char** wlst, co
 int SuggestMgr::map_related(const char * word, char * candidate, int wn, int cn,
     char** wlst, int cpdsuggest,  int ns,
     const mapentry* maptable, int nummap, int * timer, clock_t * timelimit)
 {
   if (*(word + wn) == '\0') {
       int cwrd = 1;
       *(candidate + cn) = '\0';
       int wl = strlen(candidate);
-      for (int m=0; m < ns; m++)
-          if (strcmp(candidate, wlst[m]) == 0) cwrd = 0;
+      for (int m=0; m < ns; m++) {
+          if (strcmp(candidate, wlst[m]) == 0) {
+              cwrd = 0;
+              break;
+          }
+      }
       if ((cwrd) && checkword(candidate, wl, cpdsuggest, timer, timelimit)) {
           if (ns < maxSug) {
               wlst[ns] = mystrdup(candidate);
               if (wlst[ns] == NULL) return -1;
               ns++;
           }
       }
       return ns;
@@ -727,17 +680,17 @@ int SuggestMgr::extrachar(char** wlst, c
       tmpc = tmpc2;
    }
    return ns;
 }
 
 // error is missing a letter it needs
 int SuggestMgr::forgotchar(char ** wlst, const char * word, int ns, int cpdsuggest)
 {
-   char candidate[MAXSWUTF8L];
+   char candidate[MAXSWUTF8L + 4];
    char * p;
    clock_t timelimit = clock();
    int timer = MINTIMER;
    int wl = strlen(word);
    // try inserting a tryme character before every letter (and the null terminator)
    for (int i = 0;  i < ctryl;  i++) {
       strcpy(candidate, word);
       for (p = candidate + wl;  p >= candidate; p--)  {
@@ -749,18 +702,18 @@ int SuggestMgr::forgotchar(char ** wlst,
       }
    }
    return ns;
 }
 
 // error is missing a letter it needs
 int SuggestMgr::forgotchar_utf(char ** wlst, const w_char * word, int wl, int ns, int cpdsuggest)
 {
-   w_char  candidate_utf[MAXSWL];
-   char    candidate[MAXSWUTF8L];
+   w_char  candidate_utf[MAXSWL + 1];
+   char    candidate[MAXSWUTF8L + 4];
    w_char * p;
    clock_t timelimit = clock();
    int timer = MINTIMER;
    // try inserting a tryme character at the end of the word and before every letter
    for (int i = 0;  i < ctryl;  i++) {
       memcpy (candidate_utf, word, wl * sizeof(w_char));
       for (p = candidate_utf + wl;  p >= candidate_utf; p--)  {
          *(p + 1) = *p;
@@ -810,34 +763,42 @@ int SuggestMgr::twowords(char ** wlst, c
             // spec. Hungarian code (need a better compound word support)
             if ((langnum == LANG_hu) && !forbidden &&
                 // if 3 repeating letter, use - instead of space
                 (((p[-1] == p[1]) && (((p>candidate+1) && (p[-1] == p[-2])) || (p[-1] == p[2]))) ||
                 // or multiple compounding, with more, than 6 syllables
                 ((c1 == 3) && (c2 >= 2)))) *p = '-';
 
             cwrd = 1;
-            for (int k=0; k < ns; k++)
-                if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+            for (int k=0; k < ns; k++) {
+                if (strcmp(candidate,wlst[k]) == 0) {
+                    cwrd = 0;
+                    break;
+                }
+            }
             if (ns < maxSug) {
                 if (cwrd) {
                     wlst[ns] = mystrdup(candidate);
                     if (wlst[ns] == NULL) return -1;
                     ns++;
                 }
             } else return ns;
             // add two word suggestion with dash, if TRY string contains
             // "a" or "-"
             // NOTE: cwrd doesn't modified for REP twoword sugg.
             if (ctry && (strchr(ctry, 'a') || strchr(ctry, '-')) &&
                 mystrlen(p + 1) > 1 &&
                 mystrlen(candidate) - mystrlen(p) > 1) {
                 *p = '-'; 
-                for (int k=0; k < ns; k++)
-                    if (strcmp(candidate,wlst[k]) == 0) cwrd = 0;
+                for (int k=0; k < ns; k++) {
+                    if (strcmp(candidate,wlst[k]) == 0) {
+                        cwrd = 0;
+                        break;
+                    }
+                }
                 if (ns < maxSug) {
                     if (cwrd) {
                         wlst[ns] = mystrdup(candidate);
                         if (wlst[ns] == NULL) return -1;
                         ns++;
                     }
                 } else return ns;
             }
@@ -1382,17 +1343,20 @@ int SuggestMgr::ngsuggest(char** wlst, c
                 continue;
             }
         }
         for (j = 0; j < ns; j++) {
           // don't suggest previous suggestions or a previous suggestion with prefixes or affixes
           if ((!guessorig[i] && strstr(guess[i], wlst[j])) ||
 	     (guessorig[i] && strstr(guessorig[i], wlst[j])) ||
             // check forbidden words
-            !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) unique = 0;
+            !checkword(guess[i], strlen(guess[i]), 0, NULL, NULL)) {
+            unique = 0;
+            break;
+          }
         }
         if (unique) {
     	    wlst[ns++] = guess[i];
     	    if (guessorig[i]) {
     		free(guess[i]);
     		wlst[ns-1] = guessorig[i];
     	    }
     	} else {
@@ -1410,17 +1374,20 @@ int SuggestMgr::ngsuggest(char** wlst, c
   if (ph) for (i=0; i < MAX_ROOTS; i++) {
     if (rootsphon[i]) {
       if ((ns < oldns + MAXPHONSUGS) && (ns < maxSug)) {
 	int unique = 1;
         for (j = 0; j < ns; j++) {
           // don't suggest previous suggestions or a previous suggestion with prefixes or affixes
           if (strstr(rootsphon[i], wlst[j]) || 
             // check forbidden words
-            !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) unique = 0;
+            !checkword(rootsphon[i], strlen(rootsphon[i]), 0, NULL, NULL)) {
+            unique = 0;
+            break;
+          }
         }
         if (unique) {
             wlst[ns++] = mystrdup(rootsphon[i]);
             if (!wlst[ns - 1]) return ns - 1;
         }
       }
     }
   }
@@ -1904,16 +1871,20 @@ int SuggestMgr::commoncharacterpositions
   int diff = 0;
   int diffpos[2];
   *is_swap = 0;
   if (utf8) {
     w_char su1[MAXSWL];
     w_char su2[MAXSWL];
     int l1 = u8_u16(su1, MAXSWL, s1);
     int l2 = u8_u16(su2, MAXSWL, s2);
+
+    if (l1 <= 0 || l2 <= 0)
+        return 0;
+
     // decapitalize dictionary word
     if (complexprefixes) {
       mkallsmall_utf(su2+l2-1, 1, langnum);
     } else {
       mkallsmall_utf(su2, 1, langnum);
     }
     for (int i = 0; (i < l1) && (i < l2); i++) {
       if (((short *) su1)[i] == ((short *) su2)[i]) {
--- a/extensions/spellcheck/hunspell/src/suggestmgr.hxx
+++ b/extensions/spellcheck/hunspell/src/suggestmgr.hxx
@@ -1,65 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Kevin Hendricks (kevin.hendricks@sympatico.ca)
- *                 David Einstein (deinst@world.std.com)
- *                 Lszl Nmeth (nemethl@gyorsposta.hu)
- *                 Caolan McNamara (caolanm@redhat.com)
- *                 Davide Prina
- *                 Giuseppe Modugno
- *                 Gianluca Turconi
- *                 Simon Brouwer
- *                 Noll Janos
- *                 Biro Arpad
- *                 Goldman Eleonora
- *                 Sarlos Tamas
- *                 Bencsath Boldizsar
- *                 Halacsy Peter
- *                 Dvornik Laszlo
- *                 Gefferth Andras
- *                 Nagy Viktor
- *                 Varga Daniel
- *                 Chris Halls
- *                 Rene Engelhard
- *                 Bram Moolenaar
- *                 Dafydd Jones
- *                 Harri Pitkanen
- *                 Andras Timar
- *                 Tor Lillqvist
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef _SUGGESTMGR_HXX_
 #define _SUGGESTMGR_HXX_
 
 #define MAXSWL 100
 #define MAXSWUTF8L (MAXSWL * 4)
 #define MAX_ROOTS 100
 #define MAX_WORDS 100
 #define MAX_GUESS 200
@@ -84,16 +27,20 @@
 #include "hashmgr.hxx"
 #include "langnum.hxx"
 #include <time.h>
 
 enum { LCS_UP, LCS_LEFT, LCS_UPLEFT };
 
 class LIBHUNSPELL_DLL_EXPORTED SuggestMgr
 {
+private:
+  SuggestMgr(const SuggestMgr&);
+  SuggestMgr& operator = (const SuggestMgr&);
+private:
   char *          ckey;
   int             ckeyl;
   w_char *        ckey_utf;
 
   char *          ctry;
   int             ctryl;
   w_char *        ctry_utf;
 
--- a/extensions/spellcheck/hunspell/src/w_char.hxx
+++ b/extensions/spellcheck/hunspell/src/w_char.hxx
@@ -1,41 +1,8 @@
-/******* BEGIN LICENSE BLOCK *******
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- * 
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- * 
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- * 
- * The Initial Developers of the Original Code are Kevin Hendricks (MySpell)
- * and Lszl Nmeth (Hunspell). Portions created by the Initial Developers
- * are Copyright (C) 2002-2005 the Initial Developers. All Rights Reserved.
- * 
- * Contributor(s): Lszl Nmeth (nemethl@gyorsposta.hu)
- * 
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- ******* END LICENSE BLOCK *******/
-
 #ifndef __WCHARHXX__
 #define __WCHARHXX__
 
 #ifndef GCC
 typedef struct {
 #else
 typedef struct __attribute__ ((packed)) {
 #endif