diff --git a/src/spellsuggest.c b/src/spellsuggest.c
new file mode 100644
index 0000000..41f4a73
--- /dev/null
+++ b/src/spellsuggest.c
@@ -0,0 +1,4452 @@
+/* vi:set ts=8 sts=4 sw=4 noet:
+ *
+ * VIM - Vi IMproved	by Bram Moolenaar
+ *
+ * Do ":help uganda"  in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * spellsuggest.c: functions for spelling suggestions
+ */
+
+#include "vim.h"
+
+#if defined(FEAT_SPELL) || defined(PROTO)
+
+/*
+ * Use this to adjust the score after finding suggestions, based on the
+ * suggested word sounding like the bad word.  This is much faster than doing
+ * it for every possible suggestion.
+ * Disadvantage: When "the" is typed as "hte" it sounds quite different ("@"
+ * vs "ht") and goes down in the list.
+ * Used when 'spellsuggest' is set to "best".
+ */
+#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
+
+/*
+ * Do the opposite: based on a maximum end score and a known sound score,
+ * compute the maximum word score that can be used.
+ */
+#define MAXSCORE(word_score, sound_score) ((4 * word_score - sound_score) / 3)
+
+// only used for su_badflags
+#define WF_MIXCAP   0x20	// mix of upper and lower case: macaRONI
+
+/*
+ * Information used when looking for suggestions.
+ */
+typedef struct suginfo_S
+{
+    garray_T	su_ga;		    // suggestions, contains "suggest_T"
+    int		su_maxcount;	    // max. number of suggestions displayed
+    int		su_maxscore;	    // maximum score for adding to su_ga
+    int		su_sfmaxscore;	    // idem, for when doing soundfold words
+    garray_T	su_sga;		    // like su_ga, sound-folded scoring
+    char_u	*su_badptr;	    // start of bad word in line
+    int		su_badlen;	    // length of detected bad word in line
+    int		su_badflags;	    // caps flags for bad word
+    char_u	su_badword[MAXWLEN]; // bad word truncated at su_badlen
+    char_u	su_fbadword[MAXWLEN]; // su_badword case-folded
+    char_u	su_sal_badword[MAXWLEN]; // su_badword soundfolded
+    hashtab_T	su_banned;	    // table with banned words
+    slang_T	*su_sallang;	    // default language for sound folding
+} suginfo_T;
+
+// One word suggestion.  Used in "si_ga".
+typedef struct suggest_S
+{
+    char_u	*st_word;	// suggested word, allocated string
+    int		st_wordlen;	// STRLEN(st_word)
+    int		st_orglen;	// length of replaced text
+    int		st_score;	// lower is better
+    int		st_altscore;	// used when st_score compares equal
+    int		st_salscore;	// st_score is for soundalike
+    int		st_had_bonus;	// bonus already included in score
+    slang_T	*st_slang;	// language used for sound folding
+} suggest_T;
+
+#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
+
+// TRUE if a word appears in the list of banned words.
+#define WAS_BANNED(su, word) (!HASHITEM_EMPTY(hash_find(&su->su_banned, word)))
+
+// Number of suggestions kept when cleaning up.  We need to keep more than
+// what is displayed, because when rescore_suggestions() is called the score
+// may change and wrong suggestions may be removed later.
+#define SUG_CLEAN_COUNT(su)    ((su)->su_maxcount < 130 ? 150 : (su)->su_maxcount + 20)
+
+// Threshold for sorting and cleaning up suggestions.  Don't want to keep lots
+// of suggestions that are not going to be displayed.
+#define SUG_MAX_COUNT(su)	(SUG_CLEAN_COUNT(su) + 50)
+
+// score for various changes
+#define SCORE_SPLIT	149	// split bad word
+#define SCORE_SPLIT_NO	249	// split bad word with NOSPLITSUGS
+#define SCORE_ICASE	52	// slightly different case
+#define SCORE_REGION	200	// word is for different region
+#define SCORE_RARE	180	// rare word
+#define SCORE_SWAP	75	// swap two characters
+#define SCORE_SWAP3	110	// swap two characters in three
+#define SCORE_REP	65	// REP replacement
+#define SCORE_SUBST	93	// substitute a character
+#define SCORE_SIMILAR	33	// substitute a similar character
+#define SCORE_SUBCOMP	33	// substitute a composing character
+#define SCORE_DEL	94	// delete a character
+#define SCORE_DELDUP	66	// delete a duplicated character
+#define SCORE_DELCOMP	28	// delete a composing character
+#define SCORE_INS	96	// insert a character
+#define SCORE_INSDUP	67	// insert a duplicate character
+#define SCORE_INSCOMP	30	// insert a composing character
+#define SCORE_NONWORD	103	// change non-word to word char
+
+#define SCORE_FILE	30	// suggestion from a file
+#define SCORE_MAXINIT	350	// Initial maximum score: higher == slower.
+				// 350 allows for about three changes.
+
+#define SCORE_COMMON1	30	// subtracted for words seen before
+#define SCORE_COMMON2	40	// subtracted for words often seen
+#define SCORE_COMMON3	50	// subtracted for words very often seen
+#define SCORE_THRES2	10	// word count threshold for COMMON2
+#define SCORE_THRES3	100	// word count threshold for COMMON3
+
+// When trying changed soundfold words it becomes slow when trying more than
+// two changes.  With less then two changes it's slightly faster but we miss a
+// few good suggestions.  In rare cases we need to try three of four changes.
+#define SCORE_SFMAX1	200	// maximum score for first try
+#define SCORE_SFMAX2	300	// maximum score for second try
+#define SCORE_SFMAX3	400	// maximum score for third try
+
+#define SCORE_BIG	SCORE_INS * 3	// big difference
+#define SCORE_MAXMAX	999999		// accept any score
+#define SCORE_LIMITMAX	350		// for spell_edit_score_limit()
+
+// for spell_edit_score_limit() we need to know the minimum value of
+// SCORE_ICASE, SCORE_SWAP, SCORE_DEL, SCORE_SIMILAR and SCORE_INS
+#define SCORE_EDIT_MIN	SCORE_SIMILAR
+
+/*
+ * For finding suggestions: At each node in the tree these states are tried:
+ */
+typedef enum
+{
+    STATE_START = 0,	// At start of node check for NUL bytes (goodword
+			// ends); if badword ends there is a match, otherwise
+			// try splitting word.
+    STATE_NOPREFIX,	// try without prefix
+    STATE_SPLITUNDO,	// Undo splitting.
+    STATE_ENDNUL,	// Past NUL bytes at start of the node.
+    STATE_PLAIN,	// Use each byte of the node.
+    STATE_DEL,		// Delete a byte from the bad word.
+    STATE_INS_PREP,	// Prepare for inserting bytes.
+    STATE_INS,		// Insert a byte in the bad word.
+    STATE_SWAP,		// Swap two bytes.
+    STATE_UNSWAP,	// Undo swap two characters.
+    STATE_SWAP3,	// Swap two characters over three.
+    STATE_UNSWAP3,	// Undo Swap two characters over three.
+    STATE_UNROT3L,	// Undo rotate three characters left
+    STATE_UNROT3R,	// Undo rotate three characters right
+    STATE_REP_INI,	// Prepare for using REP items.
+    STATE_REP,		// Use matching REP items from the .aff file.
+    STATE_REP_UNDO,	// Undo a REP item replacement.
+    STATE_FINAL		// End of this node.
+} state_T;
+
+/*
+ * Struct to keep the state at each level in suggest_try_change().
+ */
+typedef struct trystate_S
+{
+    state_T	ts_state;	// state at this level, STATE_
+    int		ts_score;	// score
+    idx_T	ts_arridx;	// index in tree array, start of node
+    short	ts_curi;	// index in list of child nodes
+    char_u	ts_fidx;	// index in fword[], case-folded bad word
+    char_u	ts_fidxtry;	// ts_fidx at which bytes may be changed
+    char_u	ts_twordlen;	// valid length of tword[]
+    char_u	ts_prefixdepth;	// stack depth for end of prefix or
+				// PFD_PREFIXTREE or PFD_NOPREFIX
+    char_u	ts_flags;	// TSF_ flags
+    char_u	ts_tcharlen;	// number of bytes in tword character
+    char_u	ts_tcharidx;	// current byte index in tword character
+    char_u	ts_isdiff;	// DIFF_ values
+    char_u	ts_fcharstart;	// index in fword where badword char started
+    char_u	ts_prewordlen;	// length of word in "preword[]"
+    char_u	ts_splitoff;	// index in "tword" after last split
+    char_u	ts_splitfidx;	// "ts_fidx" at word split
+    char_u	ts_complen;	// nr of compound words used
+    char_u	ts_compsplit;	// index for "compflags" where word was spit
+    char_u	ts_save_badflags;   // su_badflags saved here
+    char_u	ts_delidx;	// index in fword for char that was deleted,
+				// valid when "ts_flags" has TSF_DIDDEL
+} trystate_T;
+
+// values for ts_isdiff
+#define DIFF_NONE	0	// no different byte (yet)
+#define DIFF_YES	1	// different byte found
+#define DIFF_INSERT	2	// inserting character
+
+// values for ts_flags
+#define TSF_PREFIXOK	1	// already checked that prefix is OK
+#define TSF_DIDSPLIT	2	// tried split at this point
+#define TSF_DIDDEL	4	// did a delete, "ts_delidx" has index
+
+// special values ts_prefixdepth
+#define PFD_NOPREFIX	0xff	// not using prefixes
+#define PFD_PREFIXTREE	0xfe	// walking through the prefix tree
+#define PFD_NOTSPECIAL	0xfd	// highest value that's not special
+
+static void spell_find_suggest(char_u *badptr, int badlen, suginfo_T *su, int maxcount, int banbadword, int need_cap, int interactive);
+#ifdef FEAT_EVAL
+static void spell_suggest_expr(suginfo_T *su, char_u *expr);
+#endif
+static void spell_suggest_file(suginfo_T *su, char_u *fname);
+static void spell_suggest_intern(suginfo_T *su, int interactive);
+static void spell_find_cleanup(suginfo_T *su);
+static void suggest_try_special(suginfo_T *su);
+static void suggest_try_change(suginfo_T *su);
+static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, int soundfold);
+static void go_deeper(trystate_T *stack, int depth, int score_add);
+static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword);
+static void score_comp_sal(suginfo_T *su);
+static void score_combine(suginfo_T *su);
+static int stp_sal_score(suggest_T *stp, suginfo_T *su, slang_T *slang, char_u *badsound);
+static void suggest_try_soundalike_prep(void);
+static void suggest_try_soundalike(suginfo_T *su);
+static void suggest_try_soundalike_finish(void);
+static void add_sound_suggest(suginfo_T *su, char_u *goodword, int score, langp_T *lp);
+static int soundfold_find(slang_T *slang, char_u *word);
+static int similar_chars(slang_T *slang, int c1, int c2);
+static void add_suggestion(suginfo_T *su, garray_T *gap, char_u *goodword, int badlen, int score, int altscore, int had_bonus, slang_T *slang, int maxsf);
+static void check_suggestions(suginfo_T *su, garray_T *gap);
+static void add_banned(suginfo_T *su, char_u *word);
+static void rescore_suggestions(suginfo_T *su);
+static void rescore_one(suginfo_T *su, suggest_T *stp);
+static int cleanup_suggestions(garray_T *gap, int maxscore, int keep);
+static int soundalike_score(char_u *goodsound, char_u *badsound);
+static int spell_edit_score(slang_T *slang, char_u *badword, char_u *goodword);
+static int spell_edit_score_limit(slang_T *slang, char_u *badword, char_u *goodword, int limit);
+static int spell_edit_score_limit_w(slang_T *slang, char_u *badword, char_u *goodword, int limit);
+
+/*
+ * Return TRUE when the sequence of flags in "compflags" plus "flag" can
+ * possibly form a valid compounded word.  This also checks the COMPOUNDRULE
+ * lines if they don't contain wildcards.
+ */
+    static int
+can_be_compound(
+    trystate_T	*sp,
+    slang_T	*slang,
+    char_u	*compflags,
+    int		flag)
+{
+    // If the flag doesn't appear in sl_compstartflags or sl_compallflags
+    // then it can't possibly compound.
+    if (!byte_in_str(sp->ts_complen == sp->ts_compsplit
+		? slang->sl_compstartflags : slang->sl_compallflags, flag))
+	return FALSE;
+
+    // If there are no wildcards, we can check if the flags collected so far
+    // possibly can form a match with COMPOUNDRULE patterns.  This only
+    // makes sense when we have two or more words.
+    if (slang->sl_comprules != NULL && sp->ts_complen > sp->ts_compsplit)
+    {
+	int v;
+
+	compflags[sp->ts_complen] = flag;
+	compflags[sp->ts_complen + 1] = NUL;
+	v = match_compoundrule(slang, compflags + sp->ts_compsplit);
+	compflags[sp->ts_complen] = NUL;
+	return v;
+    }
+
+    return TRUE;
+}
+
+/*
+ * Adjust the score of common words.
+ */
+    static int
+score_wordcount_adj(
+    slang_T	*slang,
+    int		score,
+    char_u	*word,
+    int		split)	    // word was split, less bonus
+{
+    hashitem_T	*hi;
+    wordcount_T	*wc;
+    int		bonus;
+    int		newscore;
+
+    hi = hash_find(&slang->sl_wordcount, word);
+    if (!HASHITEM_EMPTY(hi))
+    {
+	wc = HI2WC(hi);
+	if (wc->wc_count < SCORE_THRES2)
+	    bonus = SCORE_COMMON1;
+	else if (wc->wc_count < SCORE_THRES3)
+	    bonus = SCORE_COMMON2;
+	else
+	    bonus = SCORE_COMMON3;
+	if (split)
+	    newscore = score - bonus / 2;
+	else
+	    newscore = score - bonus;
+	if (newscore < 0)
+	    return 0;
+	return newscore;
+    }
+    return score;
+}
+
+/*
+ * Like captype() but for a KEEPCAP word add ONECAP if the word starts with a
+ * capital.  So that make_case_word() can turn WOrd into Word.
+ * Add ALLCAP for "WOrD".
+ */
+    static int
+badword_captype(char_u *word, char_u *end)
+{
+    int		flags = captype(word, end);
+    int		c;
+    int		l, u;
+    int		first;
+    char_u	*p;
+
+    if (flags & WF_KEEPCAP)
+    {
+	// Count the number of UPPER and lower case letters.
+	l = u = 0;
+	first = FALSE;
+	for (p = word; p < end; MB_PTR_ADV(p))
+	{
+	    c = PTR2CHAR(p);
+	    if (SPELL_ISUPPER(c))
+	    {
+		++u;
+		if (p == word)
+		    first = TRUE;
+	    }
+	    else
+		++l;
+	}
+
+	// If there are more UPPER than lower case letters suggest an
+	// ALLCAP word.  Otherwise, if the first letter is UPPER then
+	// suggest ONECAP.  Exception: "ALl" most likely should be "All",
+	// require three upper case letters.
+	if (u > l && u > 2)
+	    flags |= WF_ALLCAP;
+	else if (first)
+	    flags |= WF_ONECAP;
+
+	if (u >= 2 && l >= 2)	// maCARONI maCAroni
+	    flags |= WF_MIXCAP;
+    }
+    return flags;
+}
+
+/*
+ * Opposite of offset2bytes().
+ * "pp" points to the bytes and is advanced over it.
+ * Returns the offset.
+ */
+    static int
+bytes2offset(char_u **pp)
+{
+    char_u	*p = *pp;
+    int		nr;
+    int		c;
+
+    c = *p++;
+    if ((c & 0x80) == 0x00)		// 1 byte
+    {
+	nr = c - 1;
+    }
+    else if ((c & 0xc0) == 0x80)	// 2 bytes
+    {
+	nr = (c & 0x3f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+    }
+    else if ((c & 0xe0) == 0xc0)	// 3 bytes
+    {
+	nr = (c & 0x1f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+    }
+    else				// 4 bytes
+    {
+	nr = (c & 0x0f) - 1;
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+	nr = nr * 255 + (*p++ - 1);
+    }
+
+    *pp = p;
+    return nr;
+}
+
+// values for sps_flags
+#define SPS_BEST    1
+#define SPS_FAST    2
+#define SPS_DOUBLE  4
+
+static int sps_flags = SPS_BEST;	// flags from 'spellsuggest'
+static int sps_limit = 9999;		// max nr of suggestions given
+
+/*
+ * Check the 'spellsuggest' option.  Return FAIL if it's wrong.
+ * Sets "sps_flags" and "sps_limit".
+ */
+    int
+spell_check_sps(void)
+{
+    char_u	*p;
+    char_u	*s;
+    char_u	buf[MAXPATHL];
+    int		f;
+
+    sps_flags = 0;
+    sps_limit = 9999;
+
+    for (p = p_sps; *p != NUL; )
+    {
+	copy_option_part(&p, buf, MAXPATHL, ",");
+
+	f = 0;
+	if (VIM_ISDIGIT(*buf))
+	{
+	    s = buf;
+	    sps_limit = getdigits(&s);
+	    if (*s != NUL && !VIM_ISDIGIT(*s))
+		f = -1;
+	}
+	else if (STRCMP(buf, "best") == 0)
+	    f = SPS_BEST;
+	else if (STRCMP(buf, "fast") == 0)
+	    f = SPS_FAST;
+	else if (STRCMP(buf, "double") == 0)
+	    f = SPS_DOUBLE;
+	else if (STRNCMP(buf, "expr:", 5) != 0
+		&& STRNCMP(buf, "file:", 5) != 0)
+	    f = -1;
+
+	if (f == -1 || (sps_flags != 0 && f != 0))
+	{
+	    sps_flags = SPS_BEST;
+	    sps_limit = 9999;
+	    return FAIL;
+	}
+	if (f != 0)
+	    sps_flags = f;
+    }
+
+    if (sps_flags == 0)
+	sps_flags = SPS_BEST;
+
+    return OK;
+}
+
+/*
+ * "z=": Find badly spelled word under or after the cursor.
+ * Give suggestions for the properly spelled word.
+ * In Visual mode use the highlighted word as the bad word.
+ * When "count" is non-zero use that suggestion.
+ */
+    void
+spell_suggest(int count)
+{
+    char_u	*line;
+    pos_T	prev_cursor = curwin->w_cursor;
+    char_u	wcopy[MAXWLEN + 2];
+    char_u	*p;
+    int		i;
+    int		c;
+    suginfo_T	sug;
+    suggest_T	*stp;
+    int		mouse_used;
+    int		need_cap;
+    int		limit;
+    int		selected = count;
+    int		badlen = 0;
+    int		msg_scroll_save = msg_scroll;
+
+    if (no_spell_checking(curwin))
+	return;
+
+    if (VIsual_active)
+    {
+	// Use the Visually selected text as the bad word.  But reject
+	// a multi-line selection.
+	if (curwin->w_cursor.lnum != VIsual.lnum)
+	{
+	    vim_beep(BO_SPELL);
+	    return;
+	}
+	badlen = (int)curwin->w_cursor.col - (int)VIsual.col;
+	if (badlen < 0)
+	    badlen = -badlen;
+	else
+	    curwin->w_cursor.col = VIsual.col;
+	++badlen;
+	end_visual_mode();
+    }
+    // Find the start of the badly spelled word.
+    else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
+	    || curwin->w_cursor.col > prev_cursor.col)
+    {
+	// No bad word or it starts after the cursor: use the word under the
+	// cursor.
+	curwin->w_cursor = prev_cursor;
+	line = ml_get_curline();
+	p = line + curwin->w_cursor.col;
+	// Backup to before start of word.
+	while (p > line && spell_iswordp_nmw(p, curwin))
+	    MB_PTR_BACK(line, p);
+	// Forward to start of word.
+	while (*p != NUL && !spell_iswordp_nmw(p, curwin))
+	    MB_PTR_ADV(p);
+
+	if (!spell_iswordp_nmw(p, curwin))		// No word found.
+	{
+	    beep_flush();
+	    return;
+	}
+	curwin->w_cursor.col = (colnr_T)(p - line);
+    }
+
+    // Get the word and its length.
+
+    // Figure out if the word should be capitalised.
+    need_cap = check_need_cap(curwin->w_cursor.lnum, curwin->w_cursor.col);
+
+    // Make a copy of current line since autocommands may free the line.
+    line = vim_strsave(ml_get_curline());
+    if (line == NULL)
+	goto skip;
+
+    // Get the list of suggestions.  Limit to 'lines' - 2 or the number in
+    // 'spellsuggest', whatever is smaller.
+    if (sps_limit > (int)Rows - 2)
+	limit = (int)Rows - 2;
+    else
+	limit = sps_limit;
+    spell_find_suggest(line + curwin->w_cursor.col, badlen, &sug, limit,
+							TRUE, need_cap, TRUE);
+
+    if (sug.su_ga.ga_len == 0)
+	msg(_("Sorry, no suggestions"));
+    else if (count > 0)
+    {
+	if (count > sug.su_ga.ga_len)
+	    smsg(_("Sorry, only %ld suggestions"),
+						      (long)sug.su_ga.ga_len);
+    }
+    else
+    {
+	VIM_CLEAR(repl_from);
+	VIM_CLEAR(repl_to);
+
+#ifdef FEAT_RIGHTLEFT
+	// When 'rightleft' is set the list is drawn right-left.
+	cmdmsg_rl = curwin->w_p_rl;
+	if (cmdmsg_rl)
+	    msg_col = Columns - 1;
+#endif
+
+	// List the suggestions.
+	msg_start();
+	msg_row = Rows - 1;	// for when 'cmdheight' > 1
+	lines_left = Rows;	// avoid more prompt
+	vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
+						sug.su_badlen, sug.su_badptr);
+#ifdef FEAT_RIGHTLEFT
+	if (cmdmsg_rl && STRNCMP(IObuff, "Change", 6) == 0)
+	{
+	    // And now the rabbit from the high hat: Avoid showing the
+	    // untranslated message rightleft.
+	    vim_snprintf((char *)IObuff, IOSIZE, ":ot \"%.*s\" egnahC",
+						sug.su_badlen, sug.su_badptr);
+	}
+#endif
+	msg_puts((char *)IObuff);
+	msg_clr_eos();
+	msg_putchar('\n');
+
+	msg_scroll = TRUE;
+	for (i = 0; i < sug.su_ga.ga_len; ++i)
+	{
+	    stp = &SUG(sug.su_ga, i);
+
+	    // The suggested word may replace only part of the bad word, add
+	    // the not replaced part.
+	    vim_strncpy(wcopy, stp->st_word, MAXWLEN);
+	    if (sug.su_badlen > stp->st_orglen)
+		vim_strncpy(wcopy + stp->st_wordlen,
+					       sug.su_badptr + stp->st_orglen,
+					      sug.su_badlen - stp->st_orglen);
+	    vim_snprintf((char *)IObuff, IOSIZE, "%2d", i + 1);
+#ifdef FEAT_RIGHTLEFT
+	    if (cmdmsg_rl)
+		rl_mirror(IObuff);
+#endif
+	    msg_puts((char *)IObuff);
+
+	    vim_snprintf((char *)IObuff, IOSIZE, " \"%s\"", wcopy);
+	    msg_puts((char *)IObuff);
+
+	    // The word may replace more than "su_badlen".
+	    if (sug.su_badlen < stp->st_orglen)
+	    {
+		vim_snprintf((char *)IObuff, IOSIZE, _(" < \"%.*s\""),
+					       stp->st_orglen, sug.su_badptr);
+		msg_puts((char *)IObuff);
+	    }
+
+	    if (p_verbose > 0)
+	    {
+		// Add the score.
+		if (sps_flags & (SPS_DOUBLE | SPS_BEST))
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%s%d - %d)",
+			stp->st_salscore ? "s " : "",
+			stp->st_score, stp->st_altscore);
+		else
+		    vim_snprintf((char *)IObuff, IOSIZE, " (%d)",
+			    stp->st_score);
+#ifdef FEAT_RIGHTLEFT
+		if (cmdmsg_rl)
+		    // Mirror the numbers, but keep the leading space.
+		    rl_mirror(IObuff + 1);
+#endif
+		msg_advance(30);
+		msg_puts((char *)IObuff);
+	    }
+	    msg_putchar('\n');
+	}
+
+#ifdef FEAT_RIGHTLEFT
+	cmdmsg_rl = FALSE;
+	msg_col = 0;
+#endif
+	// Ask for choice.
+	selected = prompt_for_number(&mouse_used);
+	if (mouse_used)
+	    selected -= lines_left;
+	lines_left = Rows;		// avoid more prompt
+	// don't delay for 'smd' in normal_cmd()
+	msg_scroll = msg_scroll_save;
+    }
+
+    if (selected > 0 && selected <= sug.su_ga.ga_len && u_save_cursor() == OK)
+    {
+	// Save the from and to text for :spellrepall.
+	stp = &SUG(sug.su_ga, selected - 1);
+	if (sug.su_badlen > stp->st_orglen)
+	{
+	    // Replacing less than "su_badlen", append the remainder to
+	    // repl_to.
+	    repl_from = vim_strnsave(sug.su_badptr, sug.su_badlen);
+	    vim_snprintf((char *)IObuff, IOSIZE, "%s%.*s", stp->st_word,
+		    sug.su_badlen - stp->st_orglen,
+					      sug.su_badptr + stp->st_orglen);
+	    repl_to = vim_strsave(IObuff);
+	}
+	else
+	{
+	    // Replacing su_badlen or more, use the whole word.
+	    repl_from = vim_strnsave(sug.su_badptr, stp->st_orglen);
+	    repl_to = vim_strsave(stp->st_word);
+	}
+
+	// Replace the word.
+	p = alloc(STRLEN(line) - stp->st_orglen + stp->st_wordlen + 1);
+	if (p != NULL)
+	{
+	    c = (int)(sug.su_badptr - line);
+	    mch_memmove(p, line, c);
+	    STRCPY(p + c, stp->st_word);
+	    STRCAT(p, sug.su_badptr + stp->st_orglen);
+	    ml_replace(curwin->w_cursor.lnum, p, FALSE);
+	    curwin->w_cursor.col = c;
+
+	    // For redo we use a change-word command.
+	    ResetRedobuff();
+	    AppendToRedobuff((char_u *)"ciw");
+	    AppendToRedobuffLit(p + c,
+			    stp->st_wordlen + sug.su_badlen - stp->st_orglen);
+	    AppendCharToRedobuff(ESC);
+
+	    // After this "p" may be invalid.
+	    changed_bytes(curwin->w_cursor.lnum, c);
+	}
+    }
+    else
+	curwin->w_cursor = prev_cursor;
+
+    spell_find_cleanup(&sug);
+skip:
+    vim_free(line);
+}
+
+/*
+ * Find spell suggestions for "word".  Return them in the growarray "*gap" as
+ * a list of allocated strings.
+ */
+    void
+spell_suggest_list(
+    garray_T	*gap,
+    char_u	*word,
+    int		maxcount,	// maximum nr of suggestions
+    int		need_cap,	// 'spellcapcheck' matched
+    int		interactive)
+{
+    suginfo_T	sug;
+    int		i;
+    suggest_T	*stp;
+    char_u	*wcopy;
+
+    spell_find_suggest(word, 0, &sug, maxcount, FALSE, need_cap, interactive);
+
+    // Make room in "gap".
+    ga_init2(gap, sizeof(char_u *), sug.su_ga.ga_len + 1);
+    if (ga_grow(gap, sug.su_ga.ga_len) == OK)
+    {
+	for (i = 0; i < sug.su_ga.ga_len; ++i)
+	{
+	    stp = &SUG(sug.su_ga, i);
+
+	    // The suggested word may replace only part of "word", add the not
+	    // replaced part.
+	    wcopy = alloc(stp->st_wordlen
+		      + (unsigned)STRLEN(sug.su_badptr + stp->st_orglen) + 1);
+	    if (wcopy == NULL)
+		break;
+	    STRCPY(wcopy, stp->st_word);
+	    STRCPY(wcopy + stp->st_wordlen, sug.su_badptr + stp->st_orglen);
+	    ((char_u **)gap->ga_data)[gap->ga_len++] = wcopy;
+	}
+    }
+
+    spell_find_cleanup(&sug);
+}
+
+/*
+ * Find spell suggestions for the word at the start of "badptr".
+ * Return the suggestions in "su->su_ga".
+ * The maximum number of suggestions is "maxcount".
+ * Note: does use info for the current window.
+ * This is based on the mechanisms of Aspell, but completely reimplemented.
+ */
+    static void
+spell_find_suggest(
+    char_u	*badptr,
+    int		badlen,		// length of bad word or 0 if unknown
+    suginfo_T	*su,
+    int		maxcount,
+    int		banbadword,	// don't include badword in suggestions
+    int		need_cap,	// word should start with capital
+    int		interactive)
+{
+    hlf_T	attr = HLF_COUNT;
+    char_u	buf[MAXPATHL];
+    char_u	*p;
+    int		do_combine = FALSE;
+    char_u	*sps_copy;
+#ifdef FEAT_EVAL
+    static int	expr_busy = FALSE;
+#endif
+    int		c;
+    int		i;
+    langp_T	*lp;
+
+    // Set the info in "*su".
+    vim_memset(su, 0, sizeof(suginfo_T));
+    ga_init2(&su->su_ga, (int)sizeof(suggest_T), 10);
+    ga_init2(&su->su_sga, (int)sizeof(suggest_T), 10);
+    if (*badptr == NUL)
+	return;
+    hash_init(&su->su_banned);
+
+    su->su_badptr = badptr;
+    if (badlen != 0)
+	su->su_badlen = badlen;
+    else
+	su->su_badlen = spell_check(curwin, su->su_badptr, &attr, NULL, FALSE);
+    su->su_maxcount = maxcount;
+    su->su_maxscore = SCORE_MAXINIT;
+
+    if (su->su_badlen >= MAXWLEN)
+	su->su_badlen = MAXWLEN - 1;	// just in case
+    vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
+    (void)spell_casefold(su->su_badptr, su->su_badlen,
+						    su->su_fbadword, MAXWLEN);
+    // TODO: make this work if the case-folded text is longer than the original
+    // text. Currently an illegal byte causes wrong pointer computations.
+    su->su_fbadword[su->su_badlen] = NUL;
+
+    // get caps flags for bad word
+    su->su_badflags = badword_captype(su->su_badptr,
+					       su->su_badptr + su->su_badlen);
+    if (need_cap)
+	su->su_badflags |= WF_ONECAP;
+
+    // Find the default language for sound folding.  We simply use the first
+    // one in 'spelllang' that supports sound folding.  That's good for when
+    // using multiple files for one language, it's not that bad when mixing
+    // languages (e.g., "pl,en").
+    for (i = 0; i < curbuf->b_s.b_langp.ga_len; ++i)
+    {
+	lp = LANGP_ENTRY(curbuf->b_s.b_langp, i);
+	if (lp->lp_sallang != NULL)
+	{
+	    su->su_sallang = lp->lp_sallang;
+	    break;
+	}
+    }
+
+    // Soundfold the bad word with the default sound folding, so that we don't
+    // have to do this many times.
+    if (su->su_sallang != NULL)
+	spell_soundfold(su->su_sallang, su->su_fbadword, TRUE,
+							  su->su_sal_badword);
+
+    // If the word is not capitalised and spell_check() doesn't consider the
+    // word to be bad then it might need to be capitalised.  Add a suggestion
+    // for that.
+    c = PTR2CHAR(su->su_badptr);
+    if (!SPELL_ISUPPER(c) && attr == HLF_COUNT)
+    {
+	make_case_word(su->su_badword, buf, WF_ONECAP);
+	add_suggestion(su, &su->su_ga, buf, su->su_badlen, SCORE_ICASE,
+					      0, TRUE, su->su_sallang, FALSE);
+    }
+
+    // Ban the bad word itself.  It may appear in another region.
+    if (banbadword)
+	add_banned(su, su->su_badword);
+
+    // Make a copy of 'spellsuggest', because the expression may change it.
+    sps_copy = vim_strsave(p_sps);
+    if (sps_copy == NULL)
+	return;
+
+    // Loop over the items in 'spellsuggest'.
+    for (p = sps_copy; *p != NUL; )
+    {
+	copy_option_part(&p, buf, MAXPATHL, ",");
+
+	if (STRNCMP(buf, "expr:", 5) == 0)
+	{
+#ifdef FEAT_EVAL
+	    // Evaluate an expression.  Skip this when called recursively,
+	    // when using spellsuggest() in the expression.
+	    if (!expr_busy)
+	    {
+		expr_busy = TRUE;
+		spell_suggest_expr(su, buf + 5);
+		expr_busy = FALSE;
+	    }
+#endif
+	}
+	else if (STRNCMP(buf, "file:", 5) == 0)
+	    // Use list of suggestions in a file.
+	    spell_suggest_file(su, buf + 5);
+	else
+	{
+	    // Use internal method.
+	    spell_suggest_intern(su, interactive);
+	    if (sps_flags & SPS_DOUBLE)
+		do_combine = TRUE;
+	}
+    }
+
+    vim_free(sps_copy);
+
+    if (do_combine)
+	// Combine the two list of suggestions.  This must be done last,
+	// because sorting changes the order again.
+	score_combine(su);
+}
+
+#ifdef FEAT_EVAL
+/*
+ * Find suggestions by evaluating expression "expr".
+ */
+    static void
+spell_suggest_expr(suginfo_T *su, char_u *expr)
+{
+    list_T	*list;
+    listitem_T	*li;
+    int		score;
+    char_u	*p;
+
+    // The work is split up in a few parts to avoid having to export
+    // suginfo_T.
+    // First evaluate the expression and get the resulting list.
+    list = eval_spell_expr(su->su_badword, expr);
+    if (list != NULL)
+    {
+	// Loop over the items in the list.
+	for (li = list->lv_first; li != NULL; li = li->li_next)
+	    if (li->li_tv.v_type == VAR_LIST)
+	    {
+		// Get the word and the score from the items.
+		score = get_spellword(li->li_tv.vval.v_list, &p);
+		if (score >= 0 && score <= su->su_maxscore)
+		    add_suggestion(su, &su->su_ga, p, su->su_badlen,
+				       score, 0, TRUE, su->su_sallang, FALSE);
+	    }
+	list_unref(list);
+    }
+
+    // Remove bogus suggestions, sort and truncate at "maxcount".
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+#endif
+
+/*
+ * Find suggestions in file "fname".  Used for "file:" in 'spellsuggest'.
+ */
+    static void
+spell_suggest_file(suginfo_T *su, char_u *fname)
+{
+    FILE	*fd;
+    char_u	line[MAXWLEN * 2];
+    char_u	*p;
+    int		len;
+    char_u	cword[MAXWLEN];
+
+    // Open the file.
+    fd = mch_fopen((char *)fname, "r");
+    if (fd == NULL)
+    {
+	semsg(_(e_notopen), fname);
+	return;
+    }
+
+    // Read it line by line.
+    while (!vim_fgets(line, MAXWLEN * 2, fd) && !got_int)
+    {
+	line_breakcheck();
+
+	p = vim_strchr(line, '/');
+	if (p == NULL)
+	    continue;	    // No Tab found, just skip the line.
+	*p++ = NUL;
+	if (STRICMP(su->su_badword, line) == 0)
+	{
+	    // Match!  Isolate the good word, until CR or NL.
+	    for (len = 0; p[len] >= ' '; ++len)
+		;
+	    p[len] = NUL;
+
+	    // If the suggestion doesn't have specific case duplicate the case
+	    // of the bad word.
+	    if (captype(p, NULL) == 0)
+	    {
+		make_case_word(p, cword, su->su_badflags);
+		p = cword;
+	    }
+
+	    add_suggestion(su, &su->su_ga, p, su->su_badlen,
+				  SCORE_FILE, 0, TRUE, su->su_sallang, FALSE);
+	}
+    }
+
+    fclose(fd);
+
+    // Remove bogus suggestions, sort and truncate at "maxcount".
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+}
+
+/*
+ * Find suggestions for the internal method indicated by "sps_flags".
+ */
+    static void
+spell_suggest_intern(suginfo_T *su, int interactive)
+{
+    // Load the .sug file(s) that are available and not done yet.
+    suggest_load_files();
+
+    // 1. Try special cases, such as repeating a word: "the the" -> "the".
+    //
+    // Set a maximum score to limit the combination of operations that is
+    // tried.
+    suggest_try_special(su);
+
+    // 2. Try inserting/deleting/swapping/changing a letter, use REP entries
+    //    from the .aff file and inserting a space (split the word).
+    suggest_try_change(su);
+
+    // For the resulting top-scorers compute the sound-a-like score.
+    if (sps_flags & SPS_DOUBLE)
+	score_comp_sal(su);
+
+    // 3. Try finding sound-a-like words.
+    if ((sps_flags & SPS_FAST) == 0)
+    {
+	if (sps_flags & SPS_BEST)
+	    // Adjust the word score for the suggestions found so far for how
+	    // they sounds like.
+	    rescore_suggestions(su);
+
+	// While going through the soundfold tree "su_maxscore" is the score
+	// for the soundfold word, limits the changes that are being tried,
+	// and "su_sfmaxscore" the rescored score, which is set by
+	// cleanup_suggestions().
+	// First find words with a small edit distance, because this is much
+	// faster and often already finds the top-N suggestions.  If we didn't
+	// find many suggestions try again with a higher edit distance.
+	// "sl_sounddone" is used to avoid doing the same word twice.
+	suggest_try_soundalike_prep();
+	su->su_maxscore = SCORE_SFMAX1;
+	su->su_sfmaxscore = SCORE_MAXINIT * 3;
+	suggest_try_soundalike(su);
+	if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su))
+	{
+	    // We didn't find enough matches, try again, allowing more
+	    // changes to the soundfold word.
+	    su->su_maxscore = SCORE_SFMAX2;
+	    suggest_try_soundalike(su);
+	    if (su->su_ga.ga_len < SUG_CLEAN_COUNT(su))
+	    {
+		// Still didn't find enough matches, try again, allowing even
+		// more changes to the soundfold word.
+		su->su_maxscore = SCORE_SFMAX3;
+		suggest_try_soundalike(su);
+	    }
+	}
+	su->su_maxscore = su->su_sfmaxscore;
+	suggest_try_soundalike_finish();
+    }
+
+    // When CTRL-C was hit while searching do show the results.  Only clear
+    // got_int when using a command, not for spellsuggest().
+    ui_breakcheck();
+    if (interactive && got_int)
+    {
+	(void)vgetc();
+	got_int = FALSE;
+    }
+
+    if ((sps_flags & SPS_DOUBLE) == 0 && su->su_ga.ga_len != 0)
+    {
+	if (sps_flags & SPS_BEST)
+	    // Adjust the word score for how it sounds like.
+	    rescore_suggestions(su);
+
+	// Remove bogus suggestions, sort and truncate at "maxcount".
+	check_suggestions(su, &su->su_ga);
+	(void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+    }
+}
+
+/*
+ * Free the info put in "*su" by spell_find_suggest().
+ */
+    static void
+spell_find_cleanup(suginfo_T *su)
+{
+    int		i;
+
+    // Free the suggestions.
+    for (i = 0; i < su->su_ga.ga_len; ++i)
+	vim_free(SUG(su->su_ga, i).st_word);
+    ga_clear(&su->su_ga);
+    for (i = 0; i < su->su_sga.ga_len; ++i)
+	vim_free(SUG(su->su_sga, i).st_word);
+    ga_clear(&su->su_sga);
+
+    // Free the banned words.
+    hash_clear_all(&su->su_banned, 0);
+}
+
+/*
+ * Try finding suggestions by recognizing specific situations.
+ */
+    static void
+suggest_try_special(suginfo_T *su)
+{
+    char_u	*p;
+    size_t	len;
+    int		c;
+    char_u	word[MAXWLEN];
+
+    // Recognize a word that is repeated: "the the".
+    p = skiptowhite(su->su_fbadword);
+    len = p - su->su_fbadword;
+    p = skipwhite(p);
+    if (STRLEN(p) == len && STRNCMP(su->su_fbadword, p, len) == 0)
+    {
+	// Include badflags: if the badword is onecap or allcap
+	// use that for the goodword too: "The the" -> "The".
+	c = su->su_fbadword[len];
+	su->su_fbadword[len] = NUL;
+	make_case_word(su->su_fbadword, word, su->su_badflags);
+	su->su_fbadword[len] = c;
+
+	// Give a soundalike score of 0, compute the score as if deleting one
+	// character.
+	add_suggestion(su, &su->su_ga, word, su->su_badlen,
+		       RESCORE(SCORE_REP, 0), 0, TRUE, su->su_sallang, FALSE);
+    }
+}
+
+/*
+ * Change the 0 to 1 to measure how much time is spent in each state.
+ * Output is dumped in "suggestprof".
+ */
+#if 0
+# define SUGGEST_PROFILE
+proftime_T current;
+proftime_T total;
+proftime_T times[STATE_FINAL + 1];
+long counts[STATE_FINAL + 1];
+
+    static void
+prof_init(void)
+{
+    for (int i = 0; i <= STATE_FINAL; ++i)
+    {
+	profile_zero(&times[i]);
+	counts[i] = 0;
+    }
+    profile_start(&current);
+    profile_start(&total);
+}
+
+// call before changing state
+    static void
+prof_store(state_T state)
+{
+    profile_end(&current);
+    profile_add(&times[state], &current);
+    ++counts[state];
+    profile_start(&current);
+}
+# define PROF_STORE(state) prof_store(state);
+
+    static void
+prof_report(char *name)
+{
+    FILE *fd = fopen("suggestprof", "a");
+
+    profile_end(&total);
+    fprintf(fd, "-----------------------\n");
+    fprintf(fd, "%s: %s\n", name, profile_msg(&total));
+    for (int i = 0; i <= STATE_FINAL; ++i)
+	fprintf(fd, "%d: %s (%ld)\n", i, profile_msg(&times[i]), counts[i]);
+    fclose(fd);
+}
+#else
+# define PROF_STORE(state)
+#endif
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ */
+    static void
+suggest_try_change(suginfo_T *su)
+{
+    char_u	fword[MAXWLEN];	    // copy of the bad word, case-folded
+    int		n;
+    char_u	*p;
+    int		lpi;
+    langp_T	*lp;
+
+    // We make a copy of the case-folded bad word, so that we can modify it
+    // to find matches (esp. REP items).  Append some more text, changing
+    // chars after the bad word may help.
+    STRCPY(fword, su->su_fbadword);
+    n = (int)STRLEN(fword);
+    p = su->su_badptr + su->su_badlen;
+    (void)spell_casefold(p, (int)STRLEN(p), fword + n, MAXWLEN - n);
+
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+
+	// If reloading a spell file fails it's still in the list but
+	// everything has been cleared.
+	if (lp->lp_slang->sl_fbyts == NULL)
+	    continue;
+
+	// Try it for this language.  Will add possible suggestions.
+#ifdef SUGGEST_PROFILE
+	prof_init();
+#endif
+	suggest_trie_walk(su, lp, fword, FALSE);
+#ifdef SUGGEST_PROFILE
+	prof_report("try_change");
+#endif
+    }
+}
+
+// Check the maximum score, if we go over it we won't try this change.
+#define TRY_DEEPER(su, stack, depth, add) \
+		(stack[depth].ts_score + (add) < su->su_maxscore)
+
+/*
+ * Try finding suggestions by adding/removing/swapping letters.
+ *
+ * This uses a state machine.  At each node in the tree we try various
+ * operations.  When trying if an operation works "depth" is increased and the
+ * stack[] is used to store info.  This allows combinations, thus insert one
+ * character, replace one and delete another.  The number of changes is
+ * limited by su->su_maxscore.
+ *
+ * After implementing this I noticed an article by Kemal Oflazer that
+ * describes something similar: "Error-tolerant Finite State Recognition with
+ * Applications to Morphological Analysis and Spelling Correction" (1996).
+ * The implementation in the article is simplified and requires a stack of
+ * unknown depth.  The implementation here only needs a stack depth equal to
+ * the length of the word.
+ *
+ * This is also used for the sound-folded word, "soundfold" is TRUE then.
+ * The mechanism is the same, but we find a match with a sound-folded word
+ * that comes from one or more original words.  Each of these words may be
+ * added, this is done by add_sound_suggest().
+ * Don't use:
+ *	the prefix tree or the keep-case tree
+ *	"su->su_badlen"
+ *	anything to do with upper and lower case
+ *	anything to do with word or non-word characters ("spell_iswordp()")
+ *	banned words
+ *	word flags (rare, region, compounding)
+ *	word splitting for now
+ *	"similar_chars()"
+ *	use "slang->sl_repsal" instead of "lp->lp_replang->sl_rep"
+ */
+    static void
+suggest_trie_walk(
+    suginfo_T	*su,
+    langp_T	*lp,
+    char_u	*fword,
+    int		soundfold)
+{
+    char_u	tword[MAXWLEN];	    // good word collected so far
+    trystate_T	stack[MAXWLEN];
+    char_u	preword[MAXWLEN * 3]; // word found with proper case;
+				      // concatenation of prefix compound
+				      // words and split word.  NUL terminated
+				      // when going deeper but not when coming
+				      // back.
+    char_u	compflags[MAXWLEN];	// compound flags, one for each word
+    trystate_T	*sp;
+    int		newscore;
+    int		score;
+    char_u	*byts, *fbyts, *pbyts;
+    idx_T	*idxs, *fidxs, *pidxs;
+    int		depth;
+    int		c, c2, c3;
+    int		n = 0;
+    int		flags;
+    garray_T	*gap;
+    idx_T	arridx;
+    int		len;
+    char_u	*p;
+    fromto_T	*ftp;
+    int		fl = 0, tl;
+    int		repextra = 0;	    // extra bytes in fword[] from REP item
+    slang_T	*slang = lp->lp_slang;
+    int		fword_ends;
+    int		goodword_ends;
+#ifdef DEBUG_TRIEWALK
+    // Stores the name of the change made at each level.
+    char_u	changename[MAXWLEN][80];
+#endif
+    int		breakcheckcount = 1000;
+    int		compound_ok;
+
+    // Go through the whole case-fold tree, try changes at each node.
+    // "tword[]" contains the word collected from nodes in the tree.
+    // "fword[]" the word we are trying to match with (initially the bad
+    // word).
+    depth = 0;
+    sp = &stack[0];
+    vim_memset(sp, 0, sizeof(trystate_T));
+    sp->ts_curi = 1;
+
+    if (soundfold)
+    {
+	// Going through the soundfold tree.
+	byts = fbyts = slang->sl_sbyts;
+	idxs = fidxs = slang->sl_sidxs;
+	pbyts = NULL;
+	pidxs = NULL;
+	sp->ts_prefixdepth = PFD_NOPREFIX;
+	sp->ts_state = STATE_START;
+    }
+    else
+    {
+	// When there are postponed prefixes we need to use these first.  At
+	// the end of the prefix we continue in the case-fold tree.
+	fbyts = slang->sl_fbyts;
+	fidxs = slang->sl_fidxs;
+	pbyts = slang->sl_pbyts;
+	pidxs = slang->sl_pidxs;
+	if (pbyts != NULL)
+	{
+	    byts = pbyts;
+	    idxs = pidxs;
+	    sp->ts_prefixdepth = PFD_PREFIXTREE;
+	    sp->ts_state = STATE_NOPREFIX;	// try without prefix first
+	}
+	else
+	{
+	    byts = fbyts;
+	    idxs = fidxs;
+	    sp->ts_prefixdepth = PFD_NOPREFIX;
+	    sp->ts_state = STATE_START;
+	}
+    }
+
+    // Loop to find all suggestions.  At each round we either:
+    // - For the current state try one operation, advance "ts_curi",
+    //   increase "depth".
+    // - When a state is done go to the next, set "ts_state".
+    // - When all states are tried decrease "depth".
+    while (depth >= 0 && !got_int)
+    {
+	sp = &stack[depth];
+	switch (sp->ts_state)
+	{
+	case STATE_START:
+	case STATE_NOPREFIX:
+	    // Start of node: Deal with NUL bytes, which means
+	    // tword[] may end here.
+	    arridx = sp->ts_arridx;	    // current node in the tree
+	    len = byts[arridx];		    // bytes in this node
+	    arridx += sp->ts_curi;	    // index of current byte
+
+	    if (sp->ts_prefixdepth == PFD_PREFIXTREE)
+	    {
+		// Skip over the NUL bytes, we use them later.
+		for (n = 0; n < len && byts[arridx + n] == 0; ++n)
+		    ;
+		sp->ts_curi += n;
+
+		// Always past NUL bytes now.
+		n = (int)sp->ts_state;
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_ENDNUL;
+		sp->ts_save_badflags = su->su_badflags;
+
+		// At end of a prefix or at start of prefixtree: check for
+		// following word.
+		if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX)
+		{
+		    // Set su->su_badflags to the caps type at this position.
+		    // Use the caps type until here for the prefix itself.
+		    if (has_mbyte)
+			n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+		    else
+			n = sp->ts_fidx;
+		    flags = badword_captype(su->su_badptr, su->su_badptr + n);
+		    su->su_badflags = badword_captype(su->su_badptr + n,
+					       su->su_badptr + su->su_badlen);
+#ifdef DEBUG_TRIEWALK
+		    sprintf(changename[depth], "prefix");
+#endif
+		    go_deeper(stack, depth, 0);
+		    ++depth;
+		    sp = &stack[depth];
+		    sp->ts_prefixdepth = depth - 1;
+		    byts = fbyts;
+		    idxs = fidxs;
+		    sp->ts_arridx = 0;
+
+		    // Move the prefix to preword[] with the right case
+		    // and make find_keepcap_word() works.
+		    tword[sp->ts_twordlen] = NUL;
+		    make_case_word(tword + sp->ts_splitoff,
+					  preword + sp->ts_prewordlen, flags);
+		    sp->ts_prewordlen = (char_u)STRLEN(preword);
+		    sp->ts_splitoff = sp->ts_twordlen;
+		}
+		break;
+	    }
+
+	    if (sp->ts_curi > len || byts[arridx] != 0)
+	    {
+		// Past bytes in node and/or past NUL bytes.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_ENDNUL;
+		sp->ts_save_badflags = su->su_badflags;
+		break;
+	    }
+
+	    // End of word in tree.
+	    ++sp->ts_curi;		// eat one NUL byte
+
+	    flags = (int)idxs[arridx];
+
+	    // Skip words with the NOSUGGEST flag.
+	    if (flags & WF_NOSUGGEST)
+		break;
+
+	    fword_ends = (fword[sp->ts_fidx] == NUL
+			   || (soundfold
+			       ? VIM_ISWHITE(fword[sp->ts_fidx])
+			       : !spell_iswordp(fword + sp->ts_fidx, curwin)));
+	    tword[sp->ts_twordlen] = NUL;
+
+	    if (sp->ts_prefixdepth <= PFD_NOTSPECIAL
+					&& (sp->ts_flags & TSF_PREFIXOK) == 0)
+	    {
+		// There was a prefix before the word.  Check that the prefix
+		// can be used with this word.
+		// Count the length of the NULs in the prefix.  If there are
+		// none this must be the first try without a prefix.
+		n = stack[sp->ts_prefixdepth].ts_arridx;
+		len = pbyts[n++];
+		for (c = 0; c < len && pbyts[n + c] == 0; ++c)
+		    ;
+		if (c > 0)
+		{
+		    c = valid_word_prefix(c, n, flags,
+				       tword + sp->ts_splitoff, slang, FALSE);
+		    if (c == 0)
+			break;
+
+		    // Use the WF_RARE flag for a rare prefix.
+		    if (c & WF_RAREPFX)
+			flags |= WF_RARE;
+
+		    // Tricky: when checking for both prefix and compounding
+		    // we run into the prefix flag first.
+		    // Remember that it's OK, so that we accept the prefix
+		    // when arriving at a compound flag.
+		    sp->ts_flags |= TSF_PREFIXOK;
+		}
+	    }
+
+	    // Check NEEDCOMPOUND: can't use word without compounding.  Do try
+	    // appending another compound word below.
+	    if (sp->ts_complen == sp->ts_compsplit && fword_ends
+						     && (flags & WF_NEEDCOMP))
+		goodword_ends = FALSE;
+	    else
+		goodword_ends = TRUE;
+
+	    p = NULL;
+	    compound_ok = TRUE;
+	    if (sp->ts_complen > sp->ts_compsplit)
+	    {
+		if (slang->sl_nobreak)
+		{
+		    // There was a word before this word.  When there was no
+		    // change in this word (it was correct) add the first word
+		    // as a suggestion.  If this word was corrected too, we
+		    // need to check if a correct word follows.
+		    if (sp->ts_fidx - sp->ts_splitfidx
+					  == sp->ts_twordlen - sp->ts_splitoff
+			    && STRNCMP(fword + sp->ts_splitfidx,
+					tword + sp->ts_splitoff,
+					 sp->ts_fidx - sp->ts_splitfidx) == 0)
+		    {
+			preword[sp->ts_prewordlen] = NUL;
+			newscore = score_wordcount_adj(slang, sp->ts_score,
+						 preword + sp->ts_prewordlen,
+						 sp->ts_prewordlen > 0);
+			// Add the suggestion if the score isn't too bad.
+			if (newscore <= su->su_maxscore)
+			    add_suggestion(su, &su->su_ga, preword,
+				    sp->ts_splitfidx - repextra,
+				    newscore, 0, FALSE,
+				    lp->lp_sallang, FALSE);
+			break;
+		    }
+		}
+		else
+		{
+		    // There was a compound word before this word.  If this
+		    // word does not support compounding then give up
+		    // (splitting is tried for the word without compound
+		    // flag).
+		    if (((unsigned)flags >> 24) == 0
+			    || sp->ts_twordlen - sp->ts_splitoff
+						       < slang->sl_compminlen)
+			break;
+		    // For multi-byte chars check character length against
+		    // COMPOUNDMIN.
+		    if (has_mbyte
+			    && slang->sl_compminlen > 0
+			    && mb_charlen(tword + sp->ts_splitoff)
+						       < slang->sl_compminlen)
+			break;
+
+		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+		    compflags[sp->ts_complen + 1] = NUL;
+		    vim_strncpy(preword + sp->ts_prewordlen,
+			    tword + sp->ts_splitoff,
+			    sp->ts_twordlen - sp->ts_splitoff);
+
+		    // Verify CHECKCOMPOUNDPATTERN  rules.
+		    if (match_checkcompoundpattern(preword,  sp->ts_prewordlen,
+							  &slang->sl_comppat))
+			compound_ok = FALSE;
+
+		    if (compound_ok)
+		    {
+			p = preword;
+			while (*skiptowhite(p) != NUL)
+			    p = skipwhite(skiptowhite(p));
+			if (fword_ends && !can_compound(slang, p,
+						compflags + sp->ts_compsplit))
+			    // Compound is not allowed.  But it may still be
+			    // possible if we add another (short) word.
+			    compound_ok = FALSE;
+		    }
+
+		    // Get pointer to last char of previous word.
+		    p = preword + sp->ts_prewordlen;
+		    MB_PTR_BACK(preword, p);
+		}
+	    }
+
+	    // Form the word with proper case in preword.
+	    // If there is a word from a previous split, append.
+	    // For the soundfold tree don't change the case, simply append.
+	    if (soundfold)
+		STRCPY(preword + sp->ts_prewordlen, tword + sp->ts_splitoff);
+	    else if (flags & WF_KEEPCAP)
+		// Must find the word in the keep-case tree.
+		find_keepcap_word(slang, tword + sp->ts_splitoff,
+						 preword + sp->ts_prewordlen);
+	    else
+	    {
+		// Include badflags: If the badword is onecap or allcap
+		// use that for the goodword too.  But if the badword is
+		// allcap and it's only one char long use onecap.
+		c = su->su_badflags;
+		if ((c & WF_ALLCAP)
+			&& su->su_badlen == (*mb_ptr2len)(su->su_badptr))
+		    c = WF_ONECAP;
+		c |= flags;
+
+		// When appending a compound word after a word character don't
+		// use Onecap.
+		if (p != NULL && spell_iswordp_nmw(p, curwin))
+		    c &= ~WF_ONECAP;
+		make_case_word(tword + sp->ts_splitoff,
+					      preword + sp->ts_prewordlen, c);
+	    }
+
+	    if (!soundfold)
+	    {
+		// Don't use a banned word.  It may appear again as a good
+		// word, thus remember it.
+		if (flags & WF_BANNED)
+		{
+		    add_banned(su, preword + sp->ts_prewordlen);
+		    break;
+		}
+		if ((sp->ts_complen == sp->ts_compsplit
+			    && WAS_BANNED(su, preword + sp->ts_prewordlen))
+						   || WAS_BANNED(su, preword))
+		{
+		    if (slang->sl_compprog == NULL)
+			break;
+		    // the word so far was banned but we may try compounding
+		    goodword_ends = FALSE;
+		}
+	    }
+
+	    newscore = 0;
+	    if (!soundfold)	// soundfold words don't have flags
+	    {
+		if ((flags & WF_REGION)
+			    && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+		    newscore += SCORE_REGION;
+		if (flags & WF_RARE)
+		    newscore += SCORE_RARE;
+
+		if (!spell_valid_case(su->su_badflags,
+				  captype(preword + sp->ts_prewordlen, NULL)))
+		    newscore += SCORE_ICASE;
+	    }
+
+	    // TODO: how about splitting in the soundfold tree?
+	    if (fword_ends
+		    && goodword_ends
+		    && sp->ts_fidx >= sp->ts_fidxtry
+		    && compound_ok)
+	    {
+		// The badword also ends: add suggestions.
+#ifdef DEBUG_TRIEWALK
+		if (soundfold && STRCMP(preword, "smwrd") == 0)
+		{
+		    int	    j;
+
+		    // print the stack of changes that brought us here
+		    smsg("------ %s -------", fword);
+		    for (j = 0; j < depth; ++j)
+			smsg("%s", changename[j]);
+		}
+#endif
+		if (soundfold)
+		{
+		    // For soundfolded words we need to find the original
+		    // words, the edit distance and then add them.
+		    add_sound_suggest(su, preword, sp->ts_score, lp);
+		}
+		else if (sp->ts_fidx > 0)
+		{
+		    // Give a penalty when changing non-word char to word
+		    // char, e.g., "thes," -> "these".
+		    p = fword + sp->ts_fidx;
+		    MB_PTR_BACK(fword, p);
+		    if (!spell_iswordp(p, curwin))
+		    {
+			p = preword + STRLEN(preword);
+			MB_PTR_BACK(preword, p);
+			if (spell_iswordp(p, curwin))
+			    newscore += SCORE_NONWORD;
+		    }
+
+		    // Give a bonus to words seen before.
+		    score = score_wordcount_adj(slang,
+						sp->ts_score + newscore,
+						preword + sp->ts_prewordlen,
+						sp->ts_prewordlen > 0);
+
+		    // Add the suggestion if the score isn't too bad.
+		    if (score <= su->su_maxscore)
+		    {
+			add_suggestion(su, &su->su_ga, preword,
+				    sp->ts_fidx - repextra,
+				    score, 0, FALSE, lp->lp_sallang, FALSE);
+
+			if (su->su_badflags & WF_MIXCAP)
+			{
+			    // We really don't know if the word should be
+			    // upper or lower case, add both.
+			    c = captype(preword, NULL);
+			    if (c == 0 || c == WF_ALLCAP)
+			    {
+				make_case_word(tword + sp->ts_splitoff,
+					      preword + sp->ts_prewordlen,
+						      c == 0 ? WF_ALLCAP : 0);
+
+				add_suggestion(su, &su->su_ga, preword,
+					sp->ts_fidx - repextra,
+					score + SCORE_ICASE, 0, FALSE,
+					lp->lp_sallang, FALSE);
+			    }
+			}
+		    }
+		}
+	    }
+
+	    // Try word split and/or compounding.
+	    if ((sp->ts_fidx >= sp->ts_fidxtry || fword_ends)
+		    // Don't split halfway a character.
+		    && (!has_mbyte || sp->ts_tcharlen == 0))
+	    {
+		int	try_compound;
+		int	try_split;
+
+		// If past the end of the bad word don't try a split.
+		// Otherwise try changing the next word.  E.g., find
+		// suggestions for "the the" where the second "the" is
+		// different.  It's done like a split.
+		// TODO: word split for soundfold words
+		try_split = (sp->ts_fidx - repextra < su->su_badlen)
+								&& !soundfold;
+
+		// Get here in several situations:
+		// 1. The word in the tree ends:
+		//    If the word allows compounding try that.  Otherwise try
+		//    a split by inserting a space.  For both check that a
+		//    valid words starts at fword[sp->ts_fidx].
+		//    For NOBREAK do like compounding to be able to check if
+		//    the next word is valid.
+		// 2. The badword does end, but it was due to a change (e.g.,
+		//    a swap).  No need to split, but do check that the
+		//    following word is valid.
+		// 3. The badword and the word in the tree end.  It may still
+		//    be possible to compound another (short) word.
+		try_compound = FALSE;
+		if (!soundfold
+			&& !slang->sl_nocompoundsugs
+			&& slang->sl_compprog != NULL
+			&& ((unsigned)flags >> 24) != 0
+			&& sp->ts_twordlen - sp->ts_splitoff
+						       >= slang->sl_compminlen
+			&& (!has_mbyte
+			    || slang->sl_compminlen == 0
+			    || mb_charlen(tword + sp->ts_splitoff)
+						      >= slang->sl_compminlen)
+			&& (slang->sl_compsylmax < MAXWLEN
+			    || sp->ts_complen + 1 - sp->ts_compsplit
+							  < slang->sl_compmax)
+			&& (can_be_compound(sp, slang,
+					 compflags, ((unsigned)flags >> 24))))
+
+		{
+		    try_compound = TRUE;
+		    compflags[sp->ts_complen] = ((unsigned)flags >> 24);
+		    compflags[sp->ts_complen + 1] = NUL;
+		}
+
+		// For NOBREAK we never try splitting, it won't make any word
+		// valid.
+		if (slang->sl_nobreak && !slang->sl_nocompoundsugs)
+		    try_compound = TRUE;
+
+		// If we could add a compound word, and it's also possible to
+		// split at this point, do the split first and set
+		// TSF_DIDSPLIT to avoid doing it again.
+		else if (!fword_ends
+			&& try_compound
+			&& (sp->ts_flags & TSF_DIDSPLIT) == 0)
+		{
+		    try_compound = FALSE;
+		    sp->ts_flags |= TSF_DIDSPLIT;
+		    --sp->ts_curi;	    // do the same NUL again
+		    compflags[sp->ts_complen] = NUL;
+		}
+		else
+		    sp->ts_flags &= ~TSF_DIDSPLIT;
+
+		if (try_split || try_compound)
+		{
+		    if (!try_compound && (!fword_ends || !goodword_ends))
+		    {
+			// If we're going to split need to check that the
+			// words so far are valid for compounding.  If there
+			// is only one word it must not have the NEEDCOMPOUND
+			// flag.
+			if (sp->ts_complen == sp->ts_compsplit
+						     && (flags & WF_NEEDCOMP))
+			    break;
+			p = preword;
+			while (*skiptowhite(p) != NUL)
+			    p = skipwhite(skiptowhite(p));
+			if (sp->ts_complen > sp->ts_compsplit
+				&& !can_compound(slang, p,
+						compflags + sp->ts_compsplit))
+			    break;
+
+			if (slang->sl_nosplitsugs)
+			    newscore += SCORE_SPLIT_NO;
+			else
+			    newscore += SCORE_SPLIT;
+
+			// Give a bonus to words seen before.
+			newscore = score_wordcount_adj(slang, newscore,
+					   preword + sp->ts_prewordlen, TRUE);
+		    }
+
+		    if (TRY_DEEPER(su, stack, depth, newscore))
+		    {
+			go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+			if (!try_compound && !fword_ends)
+			    sprintf(changename[depth], "%.*s-%s: split",
+				 sp->ts_twordlen, tword, fword + sp->ts_fidx);
+			else
+			    sprintf(changename[depth], "%.*s-%s: compound",
+				 sp->ts_twordlen, tword, fword + sp->ts_fidx);
+#endif
+			// Save things to be restored at STATE_SPLITUNDO.
+			sp->ts_save_badflags = su->su_badflags;
+			PROF_STORE(sp->ts_state)
+			sp->ts_state = STATE_SPLITUNDO;
+
+			++depth;
+			sp = &stack[depth];
+
+			// Append a space to preword when splitting.
+			if (!try_compound && !fword_ends)
+			    STRCAT(preword, " ");
+			sp->ts_prewordlen = (char_u)STRLEN(preword);
+			sp->ts_splitoff = sp->ts_twordlen;
+			sp->ts_splitfidx = sp->ts_fidx;
+
+			// If the badword has a non-word character at this
+			// position skip it.  That means replacing the
+			// non-word character with a space.  Always skip a
+			// character when the word ends.  But only when the
+			// good word can end.
+			if (((!try_compound && !spell_iswordp_nmw(fword
+							       + sp->ts_fidx,
+							       curwin))
+				    || fword_ends)
+				&& fword[sp->ts_fidx] != NUL
+				&& goodword_ends)
+			{
+			    int	    l;
+
+			    l = MB_PTR2LEN(fword + sp->ts_fidx);
+			    if (fword_ends)
+			    {
+				// Copy the skipped character to preword.
+				mch_memmove(preword + sp->ts_prewordlen,
+						      fword + sp->ts_fidx, l);
+				sp->ts_prewordlen += l;
+				preword[sp->ts_prewordlen] = NUL;
+			    }
+			    else
+				sp->ts_score -= SCORE_SPLIT - SCORE_SUBST;
+			    sp->ts_fidx += l;
+			}
+
+			// When compounding include compound flag in
+			// compflags[] (already set above).  When splitting we
+			// may start compounding over again.
+			if (try_compound)
+			    ++sp->ts_complen;
+			else
+			    sp->ts_compsplit = sp->ts_complen;
+			sp->ts_prefixdepth = PFD_NOPREFIX;
+
+			// set su->su_badflags to the caps type at this
+			// position
+			if (has_mbyte)
+			    n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
+			else
+			    n = sp->ts_fidx;
+			su->su_badflags = badword_captype(su->su_badptr + n,
+					       su->su_badptr + su->su_badlen);
+
+			// Restart at top of the tree.
+			sp->ts_arridx = 0;
+
+			// If there are postponed prefixes, try these too.
+			if (pbyts != NULL)
+			{
+			    byts = pbyts;
+			    idxs = pidxs;
+			    sp->ts_prefixdepth = PFD_PREFIXTREE;
+			    PROF_STORE(sp->ts_state)
+			    sp->ts_state = STATE_NOPREFIX;
+			}
+		    }
+		}
+	    }
+	    break;
+
+	case STATE_SPLITUNDO:
+	    // Undo the changes done for word split or compound word.
+	    su->su_badflags = sp->ts_save_badflags;
+
+	    // Continue looking for NUL bytes.
+	    PROF_STORE(sp->ts_state)
+	    sp->ts_state = STATE_START;
+
+	    // In case we went into the prefix tree.
+	    byts = fbyts;
+	    idxs = fidxs;
+	    break;
+
+	case STATE_ENDNUL:
+	    // Past the NUL bytes in the node.
+	    su->su_badflags = sp->ts_save_badflags;
+	    if (fword[sp->ts_fidx] == NUL && sp->ts_tcharlen == 0)
+	    {
+		// The badword ends, can't use STATE_PLAIN.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_DEL;
+		break;
+	    }
+	    PROF_STORE(sp->ts_state)
+	    sp->ts_state = STATE_PLAIN;
+	    // FALLTHROUGH
+
+	case STATE_PLAIN:
+	    // Go over all possible bytes at this node, add each to tword[]
+	    // and use child node.  "ts_curi" is the index.
+	    arridx = sp->ts_arridx;
+	    if (sp->ts_curi > byts[arridx])
+	    {
+		// Done all bytes at this node, do next state.  When still at
+		// already changed bytes skip the other tricks.
+		PROF_STORE(sp->ts_state)
+		if (sp->ts_fidx >= sp->ts_fidxtry)
+		    sp->ts_state = STATE_DEL;
+		else
+		    sp->ts_state = STATE_FINAL;
+	    }
+	    else
+	    {
+		arridx += sp->ts_curi++;
+		c = byts[arridx];
+
+		// Normal byte, go one level deeper.  If it's not equal to the
+		// byte in the bad word adjust the score.  But don't even try
+		// when the byte was already changed.  And don't try when we
+		// just deleted this byte, accepting it is always cheaper than
+		// delete + substitute.
+		if (c == fword[sp->ts_fidx]
+			|| (sp->ts_tcharlen > 0 && sp->ts_isdiff != DIFF_NONE))
+		    newscore = 0;
+		else
+		    newscore = SCORE_SUBST;
+		if ((newscore == 0
+			    || (sp->ts_fidx >= sp->ts_fidxtry
+				&& ((sp->ts_flags & TSF_DIDDEL) == 0
+				    || c != fword[sp->ts_delidx])))
+			&& TRY_DEEPER(su, stack, depth, newscore))
+		{
+		    go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		    if (newscore > 0)
+			sprintf(changename[depth], "%.*s-%s: subst %c to %c",
+				sp->ts_twordlen, tword, fword + sp->ts_fidx,
+				fword[sp->ts_fidx], c);
+		    else
+			sprintf(changename[depth], "%.*s-%s: accept %c",
+				sp->ts_twordlen, tword, fword + sp->ts_fidx,
+				fword[sp->ts_fidx]);
+#endif
+		    ++depth;
+		    sp = &stack[depth];
+		    ++sp->ts_fidx;
+		    tword[sp->ts_twordlen++] = c;
+		    sp->ts_arridx = idxs[arridx];
+		    if (newscore == SCORE_SUBST)
+			sp->ts_isdiff = DIFF_YES;
+		    if (has_mbyte)
+		    {
+			// Multi-byte characters are a bit complicated to
+			// handle: They differ when any of the bytes differ
+			// and then their length may also differ.
+			if (sp->ts_tcharlen == 0)
+			{
+			    // First byte.
+			    sp->ts_tcharidx = 0;
+			    sp->ts_tcharlen = MB_BYTE2LEN(c);
+			    sp->ts_fcharstart = sp->ts_fidx - 1;
+			    sp->ts_isdiff = (newscore != 0)
+						       ? DIFF_YES : DIFF_NONE;
+			}
+			else if (sp->ts_isdiff == DIFF_INSERT)
+			    // When inserting trail bytes don't advance in the
+			    // bad word.
+			    --sp->ts_fidx;
+			if (++sp->ts_tcharidx == sp->ts_tcharlen)
+			{
+			    // Last byte of character.
+			    if (sp->ts_isdiff == DIFF_YES)
+			    {
+				// Correct ts_fidx for the byte length of the
+				// character (we didn't check that before).
+				sp->ts_fidx = sp->ts_fcharstart
+					    + MB_PTR2LEN(
+						    fword + sp->ts_fcharstart);
+				// For changing a composing character adjust
+				// the score from SCORE_SUBST to
+				// SCORE_SUBCOMP.
+				if (enc_utf8
+					&& utf_iscomposing(
+					    utf_ptr2char(tword
+						+ sp->ts_twordlen
+							   - sp->ts_tcharlen))
+					&& utf_iscomposing(
+					    utf_ptr2char(fword
+							+ sp->ts_fcharstart)))
+				    sp->ts_score -=
+						  SCORE_SUBST - SCORE_SUBCOMP;
+
+				// For a similar character adjust score from
+				// SCORE_SUBST to SCORE_SIMILAR.
+				else if (!soundfold
+					&& slang->sl_has_map
+					&& similar_chars(slang,
+					    mb_ptr2char(tword
+						+ sp->ts_twordlen
+							   - sp->ts_tcharlen),
+					    mb_ptr2char(fword
+							+ sp->ts_fcharstart)))
+				    sp->ts_score -=
+						  SCORE_SUBST - SCORE_SIMILAR;
+			    }
+			    else if (sp->ts_isdiff == DIFF_INSERT
+					 && sp->ts_twordlen > sp->ts_tcharlen)
+			    {
+				p = tword + sp->ts_twordlen - sp->ts_tcharlen;
+				c = mb_ptr2char(p);
+				if (enc_utf8 && utf_iscomposing(c))
+				{
+				    // Inserting a composing char doesn't
+				    // count that much.
+				    sp->ts_score -= SCORE_INS - SCORE_INSCOMP;
+				}
+				else
+				{
+				    // If the previous character was the same,
+				    // thus doubling a character, give a bonus
+				    // to the score.  Also for the soundfold
+				    // tree (might seem illogical but does
+				    // give better scores).
+				    MB_PTR_BACK(tword, p);
+				    if (c == mb_ptr2char(p))
+					sp->ts_score -= SCORE_INS
+							       - SCORE_INSDUP;
+				}
+			    }
+
+			    // Starting a new char, reset the length.
+			    sp->ts_tcharlen = 0;
+			}
+		    }
+		    else
+		    {
+			// If we found a similar char adjust the score.
+			// We do this after calling go_deeper() because
+			// it's slow.
+			if (newscore != 0
+				&& !soundfold
+				&& slang->sl_has_map
+				&& similar_chars(slang,
+						   c, fword[sp->ts_fidx - 1]))
+			    sp->ts_score -= SCORE_SUBST - SCORE_SIMILAR;
+		    }
+		}
+	    }
+	    break;
+
+	case STATE_DEL:
+	    // When past the first byte of a multi-byte char don't try
+	    // delete/insert/swap a character.
+	    if (has_mbyte && sp->ts_tcharlen > 0)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+	    // Try skipping one character in the bad word (delete it).
+	    PROF_STORE(sp->ts_state)
+	    sp->ts_state = STATE_INS_PREP;
+	    sp->ts_curi = 1;
+	    if (soundfold && sp->ts_fidx == 0 && fword[sp->ts_fidx] == '*')
+		// Deleting a vowel at the start of a word counts less, see
+		// soundalike_score().
+		newscore = 2 * SCORE_DEL / 3;
+	    else
+		newscore = SCORE_DEL;
+	    if (fword[sp->ts_fidx] != NUL
+				    && TRY_DEEPER(su, stack, depth, newscore))
+	    {
+		go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: delete %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			fword[sp->ts_fidx]);
+#endif
+		++depth;
+
+		// Remember what character we deleted, so that we can avoid
+		// inserting it again.
+		stack[depth].ts_flags |= TSF_DIDDEL;
+		stack[depth].ts_delidx = sp->ts_fidx;
+
+		// Advance over the character in fword[].  Give a bonus to the
+		// score if the same character is following "nn" -> "n".  It's
+		// a bit illogical for soundfold tree but it does give better
+		// results.
+		if (has_mbyte)
+		{
+		    c = mb_ptr2char(fword + sp->ts_fidx);
+		    stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
+		    if (enc_utf8 && utf_iscomposing(c))
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
+		    else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+		}
+		else
+		{
+		    ++stack[depth].ts_fidx;
+		    if (fword[sp->ts_fidx] == fword[sp->ts_fidx + 1])
+			stack[depth].ts_score -= SCORE_DEL - SCORE_DELDUP;
+		}
+		break;
+	    }
+	    // FALLTHROUGH
+
+	case STATE_INS_PREP:
+	    if (sp->ts_flags & TSF_DIDDEL)
+	    {
+		// If we just deleted a byte then inserting won't make sense,
+		// a substitute is always cheaper.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_SWAP;
+		break;
+	    }
+
+	    // skip over NUL bytes
+	    n = sp->ts_arridx;
+	    for (;;)
+	    {
+		if (sp->ts_curi > byts[n])
+		{
+		    // Only NUL bytes at this node, go to next state.
+		    PROF_STORE(sp->ts_state)
+		    sp->ts_state = STATE_SWAP;
+		    break;
+		}
+		if (byts[n + sp->ts_curi] != NUL)
+		{
+		    // Found a byte to insert.
+		    PROF_STORE(sp->ts_state)
+		    sp->ts_state = STATE_INS;
+		    break;
+		}
+		++sp->ts_curi;
+	    }
+	    break;
+
+	    // FALLTHROUGH
+
+	case STATE_INS:
+	    // Insert one byte.  Repeat this for each possible byte at this
+	    // node.
+	    n = sp->ts_arridx;
+	    if (sp->ts_curi > byts[n])
+	    {
+		// Done all bytes at this node, go to next state.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_SWAP;
+		break;
+	    }
+
+	    // Do one more byte at this node, but:
+	    // - Skip NUL bytes.
+	    // - Skip the byte if it's equal to the byte in the word,
+	    //   accepting that byte is always better.
+	    n += sp->ts_curi++;
+	    c = byts[n];
+	    if (soundfold && sp->ts_twordlen == 0 && c == '*')
+		// Inserting a vowel at the start of a word counts less,
+		// see soundalike_score().
+		newscore = 2 * SCORE_INS / 3;
+	    else
+		newscore = SCORE_INS;
+	    if (c != fword[sp->ts_fidx]
+				    && TRY_DEEPER(su, stack, depth, newscore))
+	    {
+		go_deeper(stack, depth, newscore);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: insert %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c);
+#endif
+		++depth;
+		sp = &stack[depth];
+		tword[sp->ts_twordlen++] = c;
+		sp->ts_arridx = idxs[n];
+		if (has_mbyte)
+		{
+		    fl = MB_BYTE2LEN(c);
+		    if (fl > 1)
+		    {
+			// There are following bytes for the same character.
+			// We must find all bytes before trying
+			// delete/insert/swap/etc.
+			sp->ts_tcharlen = fl;
+			sp->ts_tcharidx = 1;
+			sp->ts_isdiff = DIFF_INSERT;
+		    }
+		}
+		else
+		    fl = 1;
+		if (fl == 1)
+		{
+		    // If the previous character was the same, thus doubling a
+		    // character, give a bonus to the score.  Also for
+		    // soundfold words (illogical but does give a better
+		    // score).
+		    if (sp->ts_twordlen >= 2
+					   && tword[sp->ts_twordlen - 2] == c)
+			sp->ts_score -= SCORE_INS - SCORE_INSDUP;
+		}
+	    }
+	    break;
+
+	case STATE_SWAP:
+	    // Swap two bytes in the bad word: "12" -> "21".
+	    // We change "fword" here, it's changed back afterwards at
+	    // STATE_UNSWAP.
+	    p = fword + sp->ts_fidx;
+	    c = *p;
+	    if (c == NUL)
+	    {
+		// End of word, can't swap or replace.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    // Don't swap if the first character is not a word character.
+	    // SWAP3 etc. also don't make sense then.
+	    if (!soundfold && !spell_iswordp(p, curwin))
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+
+	    if (has_mbyte)
+	    {
+		n = MB_CPTR2LEN(p);
+		c = mb_ptr2char(p);
+		if (p[n] == NUL)
+		    c2 = NUL;
+		else if (!soundfold && !spell_iswordp(p + n, curwin))
+		    c2 = c; // don't swap non-word char
+		else
+		    c2 = mb_ptr2char(p + n);
+	    }
+	    else
+	    {
+		if (p[1] == NUL)
+		    c2 = NUL;
+		else if (!soundfold && !spell_iswordp(p + 1, curwin))
+		    c2 = c; // don't swap non-word char
+		else
+		    c2 = p[1];
+	    }
+
+	    // When the second character is NUL we can't swap.
+	    if (c2 == NUL)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+
+	    // When characters are identical, swap won't do anything.
+	    // Also get here if the second char is not a word character.
+	    if (c == c2)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_SWAP3;
+		break;
+	    }
+	    if (c2 != NUL && TRY_DEEPER(su, stack, depth, SCORE_SWAP))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: swap %c and %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c, c2);
+#endif
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_UNSWAP;
+		++depth;
+		if (has_mbyte)
+		{
+		    fl = mb_char2len(c2);
+		    mch_memmove(p, p + n, fl);
+		    mb_char2bytes(c, p + fl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
+		}
+		else
+		{
+		    p[0] = c2;
+		    p[1] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 2;
+		}
+	    }
+	    else
+	    {
+		// If this swap doesn't work then SWAP3 won't either.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+	    }
+	    break;
+
+	case STATE_UNSWAP:
+	    // Undo the STATE_SWAP swap: "21" -> "12".
+	    p = fword + sp->ts_fidx;
+	    if (has_mbyte)
+	    {
+		n = MB_PTR2LEN(p);
+		c = mb_ptr2char(p + n);
+		mch_memmove(p + MB_PTR2LEN(p + n), p, n);
+		mb_char2bytes(c, p);
+	    }
+	    else
+	    {
+		c = *p;
+		*p = p[1];
+		p[1] = c;
+	    }
+	    // FALLTHROUGH
+
+	case STATE_SWAP3:
+	    // Swap two bytes, skipping one: "123" -> "321".  We change
+	    // "fword" here, it's changed back afterwards at STATE_UNSWAP3.
+	    p = fword + sp->ts_fidx;
+	    if (has_mbyte)
+	    {
+		n = MB_CPTR2LEN(p);
+		c = mb_ptr2char(p);
+		fl = MB_CPTR2LEN(p + n);
+		c2 = mb_ptr2char(p + n);
+		if (!soundfold && !spell_iswordp(p + n + fl, curwin))
+		    c3 = c;	// don't swap non-word char
+		else
+		    c3 = mb_ptr2char(p + n + fl);
+	    }
+	    else
+	    {
+		c = *p;
+		c2 = p[1];
+		if (!soundfold && !spell_iswordp(p + 2, curwin))
+		    c3 = c;	// don't swap non-word char
+		else
+		    c3 = p[2];
+	    }
+
+	    // When characters are identical: "121" then SWAP3 result is
+	    // identical, ROT3L result is same as SWAP: "211", ROT3L result is
+	    // same as SWAP on next char: "112".  Thus skip all swapping.
+	    // Also skip when c3 is NUL.
+	    // Also get here when the third character is not a word character.
+	    // Second character may any char: "a.b" -> "b.a"
+	    if (c == c3 || c3 == NUL)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		sprintf(changename[depth], "%.*s-%s: swap3 %c and %c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			c, c3);
+#endif
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_UNSWAP3;
+		++depth;
+		if (has_mbyte)
+		{
+		    tl = mb_char2len(c3);
+		    mch_memmove(p, p + n + fl, tl);
+		    mb_char2bytes(c2, p + tl);
+		    mb_char2bytes(c, p + fl + tl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl + tl;
+		}
+		else
+		{
+		    p[0] = p[2];
+		    p[2] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+	    }
+	    break;
+
+	case STATE_UNSWAP3:
+	    // Undo STATE_SWAP3: "321" -> "123"
+	    p = fword + sp->ts_fidx;
+	    if (has_mbyte)
+	    {
+		n = MB_PTR2LEN(p);
+		c2 = mb_ptr2char(p + n);
+		fl = MB_PTR2LEN(p + n);
+		c = mb_ptr2char(p + n + fl);
+		tl = MB_PTR2LEN(p + n + fl);
+		mch_memmove(p + fl + tl, p, n);
+		mb_char2bytes(c, p);
+		mb_char2bytes(c2, p + tl);
+		p = p + tl;
+	    }
+	    else
+	    {
+		c = *p;
+		*p = p[2];
+		p[2] = c;
+		++p;
+	    }
+
+	    if (!soundfold && !spell_iswordp(p, curwin))
+	    {
+		// Middle char is not a word char, skip the rotate.  First and
+		// third char were already checked at swap and swap3.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+		break;
+	    }
+
+	    // Rotate three characters left: "123" -> "231".  We change
+	    // "fword" here, it's changed back afterwards at STATE_UNROT3L.
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		p = fword + sp->ts_fidx;
+		sprintf(changename[depth], "%.*s-%s: rotate left %c%c%c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			p[0], p[1], p[2]);
+#endif
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_UNROT3L;
+		++depth;
+		p = fword + sp->ts_fidx;
+		if (has_mbyte)
+		{
+		    n = MB_CPTR2LEN(p);
+		    c = mb_ptr2char(p);
+		    fl = MB_CPTR2LEN(p + n);
+		    fl += MB_CPTR2LEN(p + n + fl);
+		    mch_memmove(p, p + n, fl);
+		    mb_char2bytes(c, p + fl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
+		}
+		else
+		{
+		    c = *p;
+		    *p = p[1];
+		    p[1] = p[2];
+		    p[2] = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+	    }
+	    break;
+
+	case STATE_UNROT3L:
+	    // Undo ROT3L: "231" -> "123"
+	    p = fword + sp->ts_fidx;
+	    if (has_mbyte)
+	    {
+		n = MB_PTR2LEN(p);
+		n += MB_PTR2LEN(p + n);
+		c = mb_ptr2char(p + n);
+		tl = MB_PTR2LEN(p + n);
+		mch_memmove(p + tl, p, n);
+		mb_char2bytes(c, p);
+	    }
+	    else
+	    {
+		c = p[2];
+		p[2] = p[1];
+		p[1] = *p;
+		*p = c;
+	    }
+
+	    // Rotate three bytes right: "123" -> "312".  We change "fword"
+	    // here, it's changed back afterwards at STATE_UNROT3R.
+	    if (TRY_DEEPER(su, stack, depth, SCORE_SWAP3))
+	    {
+		go_deeper(stack, depth, SCORE_SWAP3);
+#ifdef DEBUG_TRIEWALK
+		p = fword + sp->ts_fidx;
+		sprintf(changename[depth], "%.*s-%s: rotate right %c%c%c",
+			sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			p[0], p[1], p[2]);
+#endif
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_UNROT3R;
+		++depth;
+		p = fword + sp->ts_fidx;
+		if (has_mbyte)
+		{
+		    n = MB_CPTR2LEN(p);
+		    n += MB_CPTR2LEN(p + n);
+		    c = mb_ptr2char(p + n);
+		    tl = MB_CPTR2LEN(p + n);
+		    mch_memmove(p + tl, p, n);
+		    mb_char2bytes(c, p);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
+		}
+		else
+		{
+		    c = p[2];
+		    p[2] = p[1];
+		    p[1] = *p;
+		    *p = c;
+		    stack[depth].ts_fidxtry = sp->ts_fidx + 3;
+		}
+	    }
+	    else
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_REP_INI;
+	    }
+	    break;
+
+	case STATE_UNROT3R:
+	    // Undo ROT3R: "312" -> "123"
+	    p = fword + sp->ts_fidx;
+	    if (has_mbyte)
+	    {
+		c = mb_ptr2char(p);
+		tl = MB_PTR2LEN(p);
+		n = MB_PTR2LEN(p + tl);
+		n += MB_PTR2LEN(p + tl + n);
+		mch_memmove(p, p + tl, n);
+		mb_char2bytes(c, p + n);
+	    }
+	    else
+	    {
+		c = *p;
+		*p = p[1];
+		p[1] = p[2];
+		p[2] = c;
+	    }
+	    // FALLTHROUGH
+
+	case STATE_REP_INI:
+	    // Check if matching with REP items from the .aff file would work.
+	    // Quickly skip if:
+	    // - there are no REP items and we are not in the soundfold trie
+	    // - the score is going to be too high anyway
+	    // - already applied a REP item or swapped here
+	    if ((lp->lp_replang == NULL && !soundfold)
+		    || sp->ts_score + SCORE_REP >= su->su_maxscore
+		    || sp->ts_fidx < sp->ts_fidxtry)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    // Use the first byte to quickly find the first entry that may
+	    // match.  If the index is -1 there is none.
+	    if (soundfold)
+		sp->ts_curi = slang->sl_repsal_first[fword[sp->ts_fidx]];
+	    else
+		sp->ts_curi = lp->lp_replang->sl_rep_first[fword[sp->ts_fidx]];
+
+	    if (sp->ts_curi < 0)
+	    {
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_FINAL;
+		break;
+	    }
+
+	    PROF_STORE(sp->ts_state)
+	    sp->ts_state = STATE_REP;
+	    // FALLTHROUGH
+
+	case STATE_REP:
+	    // Try matching with REP items from the .aff file.  For each match
+	    // replace the characters and check if the resulting word is
+	    // valid.
+	    p = fword + sp->ts_fidx;
+
+	    if (soundfold)
+		gap = &slang->sl_repsal;
+	    else
+		gap = &lp->lp_replang->sl_rep;
+	    while (sp->ts_curi < gap->ga_len)
+	    {
+		ftp = (fromto_T *)gap->ga_data + sp->ts_curi++;
+		if (*ftp->ft_from != *p)
+		{
+		    // past possible matching entries
+		    sp->ts_curi = gap->ga_len;
+		    break;
+		}
+		if (STRNCMP(ftp->ft_from, p, STRLEN(ftp->ft_from)) == 0
+			&& TRY_DEEPER(su, stack, depth, SCORE_REP))
+		{
+		    go_deeper(stack, depth, SCORE_REP);
+#ifdef DEBUG_TRIEWALK
+		    sprintf(changename[depth], "%.*s-%s: replace %s with %s",
+			    sp->ts_twordlen, tword, fword + sp->ts_fidx,
+			    ftp->ft_from, ftp->ft_to);
+#endif
+		    // Need to undo this afterwards.
+		    PROF_STORE(sp->ts_state)
+		    sp->ts_state = STATE_REP_UNDO;
+
+		    // Change the "from" to the "to" string.
+		    ++depth;
+		    fl = (int)STRLEN(ftp->ft_from);
+		    tl = (int)STRLEN(ftp->ft_to);
+		    if (fl != tl)
+		    {
+			STRMOVE(p + tl, p + fl);
+			repextra += tl - fl;
+		    }
+		    mch_memmove(p, ftp->ft_to, tl);
+		    stack[depth].ts_fidxtry = sp->ts_fidx + tl;
+		    stack[depth].ts_tcharlen = 0;
+		    break;
+		}
+	    }
+
+	    if (sp->ts_curi >= gap->ga_len && sp->ts_state == STATE_REP)
+	    {
+		// No (more) matches.
+		PROF_STORE(sp->ts_state)
+		sp->ts_state = STATE_FINAL;
+	    }
+
+	    break;
+
+	case STATE_REP_UNDO:
+	    // Undo a REP replacement and continue with the next one.
+	    if (soundfold)
+		gap = &slang->sl_repsal;
+	    else
+		gap = &lp->lp_replang->sl_rep;
+	    ftp = (fromto_T *)gap->ga_data + sp->ts_curi - 1;
+	    fl = (int)STRLEN(ftp->ft_from);
+	    tl = (int)STRLEN(ftp->ft_to);
+	    p = fword + sp->ts_fidx;
+	    if (fl != tl)
+	    {
+		STRMOVE(p + fl, p + tl);
+		repextra -= tl - fl;
+	    }
+	    mch_memmove(p, ftp->ft_from, fl);
+	    PROF_STORE(sp->ts_state)
+	    sp->ts_state = STATE_REP;
+	    break;
+
+	default:
+	    // Did all possible states at this level, go up one level.
+	    --depth;
+
+	    if (depth >= 0 && stack[depth].ts_prefixdepth == PFD_PREFIXTREE)
+	    {
+		// Continue in or go back to the prefix tree.
+		byts = pbyts;
+		idxs = pidxs;
+	    }
+
+	    // Don't check for CTRL-C too often, it takes time.
+	    if (--breakcheckcount == 0)
+	    {
+		ui_breakcheck();
+		breakcheckcount = 1000;
+	    }
+	}
+    }
+}
+
+
+/*
+ * Go one level deeper in the tree.
+ */
+    static void
+go_deeper(trystate_T *stack, int depth, int score_add)
+{
+    stack[depth + 1] = stack[depth];
+    stack[depth + 1].ts_state = STATE_START;
+    stack[depth + 1].ts_score = stack[depth].ts_score + score_add;
+    stack[depth + 1].ts_curi = 1;	// start just after length byte
+    stack[depth + 1].ts_flags = 0;
+}
+
+/*
+ * "fword" is a good word with case folded.  Find the matching keep-case
+ * words and put it in "kword".
+ * Theoretically there could be several keep-case words that result in the
+ * same case-folded word, but we only find one...
+ */
+    static void
+find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
+{
+    char_u	uword[MAXWLEN];		// "fword" in upper-case
+    int		depth;
+    idx_T	tryidx;
+
+    // The following arrays are used at each depth in the tree.
+    idx_T	arridx[MAXWLEN];
+    int		round[MAXWLEN];
+    int		fwordidx[MAXWLEN];
+    int		uwordidx[MAXWLEN];
+    int		kwordlen[MAXWLEN];
+
+    int		flen, ulen;
+    int		l;
+    int		len;
+    int		c;
+    idx_T	lo, hi, m;
+    char_u	*p;
+    char_u	*byts = slang->sl_kbyts;    // array with bytes of the words
+    idx_T	*idxs = slang->sl_kidxs;    // array with indexes
+
+    if (byts == NULL)
+    {
+	// array is empty: "cannot happen"
+	*kword = NUL;
+	return;
+    }
+
+    // Make an all-cap version of "fword".
+    allcap_copy(fword, uword);
+
+    // Each character needs to be tried both case-folded and upper-case.
+    // All this gets very complicated if we keep in mind that changing case
+    // may change the byte length of a multi-byte character...
+    depth = 0;
+    arridx[0] = 0;
+    round[0] = 0;
+    fwordidx[0] = 0;
+    uwordidx[0] = 0;
+    kwordlen[0] = 0;
+    while (depth >= 0)
+    {
+	if (fword[fwordidx[depth]] == NUL)
+	{
+	    // We are at the end of "fword".  If the tree allows a word to end
+	    // here we have found a match.
+	    if (byts[arridx[depth] + 1] == 0)
+	    {
+		kword[kwordlen[depth]] = NUL;
+		return;
+	    }
+
+	    // kword is getting too long, continue one level up
+	    --depth;
+	}
+	else if (++round[depth] > 2)
+	{
+	    // tried both fold-case and upper-case character, continue one
+	    // level up
+	    --depth;
+	}
+	else
+	{
+	    // round[depth] == 1: Try using the folded-case character.
+	    // round[depth] == 2: Try using the upper-case character.
+	    if (has_mbyte)
+	    {
+		flen = MB_CPTR2LEN(fword + fwordidx[depth]);
+		ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
+	    }
+	    else
+		ulen = flen = 1;
+	    if (round[depth] == 1)
+	    {
+		p = fword + fwordidx[depth];
+		l = flen;
+	    }
+	    else
+	    {
+		p = uword + uwordidx[depth];
+		l = ulen;
+	    }
+
+	    for (tryidx = arridx[depth]; l > 0; --l)
+	    {
+		// Perform a binary search in the list of accepted bytes.
+		len = byts[tryidx++];
+		c = *p++;
+		lo = tryidx;
+		hi = tryidx + len - 1;
+		while (lo < hi)
+		{
+		    m = (lo + hi) / 2;
+		    if (byts[m] > c)
+			hi = m - 1;
+		    else if (byts[m] < c)
+			lo = m + 1;
+		    else
+		    {
+			lo = hi = m;
+			break;
+		    }
+		}
+
+		// Stop if there is no matching byte.
+		if (hi < lo || byts[lo] != c)
+		    break;
+
+		// Continue at the child (if there is one).
+		tryidx = idxs[lo];
+	    }
+
+	    if (l == 0)
+	    {
+		// Found the matching char.  Copy it to "kword" and go a
+		// level deeper.
+		if (round[depth] == 1)
+		{
+		    STRNCPY(kword + kwordlen[depth], fword + fwordidx[depth],
+									flen);
+		    kwordlen[depth + 1] = kwordlen[depth] + flen;
+		}
+		else
+		{
+		    STRNCPY(kword + kwordlen[depth], uword + uwordidx[depth],
+									ulen);
+		    kwordlen[depth + 1] = kwordlen[depth] + ulen;
+		}
+		fwordidx[depth + 1] = fwordidx[depth] + flen;
+		uwordidx[depth + 1] = uwordidx[depth] + ulen;
+
+		++depth;
+		arridx[depth] = tryidx;
+		round[depth] = 0;
+	    }
+	}
+    }
+
+    // Didn't find it: "cannot happen".
+    *kword = NUL;
+}
+
+/*
+ * Compute the sound-a-like score for suggestions in su->su_ga and add them to
+ * su->su_sga.
+ */
+    static void
+score_comp_sal(suginfo_T *su)
+{
+    langp_T	*lp;
+    char_u	badsound[MAXWLEN];
+    int		i;
+    suggest_T   *stp;
+    suggest_T   *sstp;
+    int		score;
+    int		lpi;
+
+    if (ga_grow(&su->su_sga, su->su_ga.ga_len) == FAIL)
+	return;
+
+    // Use the sound-folding of the first language that supports it.
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    // soundfold the bad word
+	    spell_soundfold(lp->lp_slang, su->su_fbadword, TRUE, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+
+		// Case-fold the suggested word, sound-fold it and compute the
+		// sound-a-like score.
+		score = stp_sal_score(stp, su, lp->lp_slang, badsound);
+		if (score < SCORE_MAXMAX)
+		{
+		    // Add the suggestion.
+		    sstp = &SUG(su->su_sga, su->su_sga.ga_len);
+		    sstp->st_word = vim_strsave(stp->st_word);
+		    if (sstp->st_word != NULL)
+		    {
+			sstp->st_wordlen = stp->st_wordlen;
+			sstp->st_score = score;
+			sstp->st_altscore = 0;
+			sstp->st_orglen = stp->st_orglen;
+			++su->su_sga.ga_len;
+		    }
+		}
+	    }
+	    break;
+	}
+    }
+}
+
+/*
+ * Combine the list of suggestions in su->su_ga and su->su_sga.
+ * They are entwined.
+ */
+    static void
+score_combine(suginfo_T *su)
+{
+    int		i;
+    int		j;
+    garray_T	ga;
+    garray_T	*gap;
+    langp_T	*lp;
+    suggest_T	*stp;
+    char_u	*p;
+    char_u	badsound[MAXWLEN];
+    int		round;
+    int		lpi;
+    slang_T	*slang = NULL;
+
+    // Add the alternate score to su_ga.
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    // soundfold the bad word
+	    slang = lp->lp_slang;
+	    spell_soundfold(slang, su->su_fbadword, TRUE, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+		stp->st_altscore = stp_sal_score(stp, su, slang, badsound);
+		if (stp->st_altscore == SCORE_MAXMAX)
+		    stp->st_score = (stp->st_score * 3 + SCORE_BIG) / 4;
+		else
+		    stp->st_score = (stp->st_score * 3
+						  + stp->st_altscore) / 4;
+		stp->st_salscore = FALSE;
+	    }
+	    break;
+	}
+    }
+
+    if (slang == NULL)	// Using "double" without sound folding.
+    {
+	(void)cleanup_suggestions(&su->su_ga, su->su_maxscore,
+							     su->su_maxcount);
+	return;
+    }
+
+    // Add the alternate score to su_sga.
+    for (i = 0; i < su->su_sga.ga_len; ++i)
+    {
+	stp = &SUG(su->su_sga, i);
+	stp->st_altscore = spell_edit_score(slang,
+						su->su_badword, stp->st_word);
+	if (stp->st_score == SCORE_MAXMAX)
+	    stp->st_score = (SCORE_BIG * 7 + stp->st_altscore) / 8;
+	else
+	    stp->st_score = (stp->st_score * 7 + stp->st_altscore) / 8;
+	stp->st_salscore = TRUE;
+    }
+
+    // Remove bad suggestions, sort the suggestions and truncate at "maxcount"
+    // for both lists.
+    check_suggestions(su, &su->su_ga);
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+    check_suggestions(su, &su->su_sga);
+    (void)cleanup_suggestions(&su->su_sga, su->su_maxscore, su->su_maxcount);
+
+    ga_init2(&ga, (int)sizeof(suginfo_T), 1);
+    if (ga_grow(&ga, su->su_ga.ga_len + su->su_sga.ga_len) == FAIL)
+	return;
+
+    stp = &SUG(ga, 0);
+    for (i = 0; i < su->su_ga.ga_len || i < su->su_sga.ga_len; ++i)
+    {
+	// round 1: get a suggestion from su_ga
+	// round 2: get a suggestion from su_sga
+	for (round = 1; round <= 2; ++round)
+	{
+	    gap = round == 1 ? &su->su_ga : &su->su_sga;
+	    if (i < gap->ga_len)
+	    {
+		// Don't add a word if it's already there.
+		p = SUG(*gap, i).st_word;
+		for (j = 0; j < ga.ga_len; ++j)
+		    if (STRCMP(stp[j].st_word, p) == 0)
+			break;
+		if (j == ga.ga_len)
+		    stp[ga.ga_len++] = SUG(*gap, i);
+		else
+		    vim_free(p);
+	    }
+	}
+    }
+
+    ga_clear(&su->su_ga);
+    ga_clear(&su->su_sga);
+
+    // Truncate the list to the number of suggestions that will be displayed.
+    if (ga.ga_len > su->su_maxcount)
+    {
+	for (i = su->su_maxcount; i < ga.ga_len; ++i)
+	    vim_free(stp[i].st_word);
+	ga.ga_len = su->su_maxcount;
+    }
+
+    su->su_ga = ga;
+}
+
+/*
+ * For the goodword in "stp" compute the soundalike score compared to the
+ * badword.
+ */
+    static int
+stp_sal_score(
+    suggest_T	*stp,
+    suginfo_T	*su,
+    slang_T	*slang,
+    char_u	*badsound)	// sound-folded badword
+{
+    char_u	*p;
+    char_u	*pbad;
+    char_u	*pgood;
+    char_u	badsound2[MAXWLEN];
+    char_u	fword[MAXWLEN];
+    char_u	goodsound[MAXWLEN];
+    char_u	goodword[MAXWLEN];
+    int		lendiff;
+
+    lendiff = (int)(su->su_badlen - stp->st_orglen);
+    if (lendiff >= 0)
+	pbad = badsound;
+    else
+    {
+	// soundfold the bad word with more characters following
+	(void)spell_casefold(su->su_badptr, stp->st_orglen, fword, MAXWLEN);
+
+	// When joining two words the sound often changes a lot.  E.g., "t he"
+	// sounds like "t h" while "the" sounds like "@".  Avoid that by
+	// removing the space.  Don't do it when the good word also contains a
+	// space.
+	if (VIM_ISWHITE(su->su_badptr[su->su_badlen])
+					 && *skiptowhite(stp->st_word) == NUL)
+	    for (p = fword; *(p = skiptowhite(p)) != NUL; )
+		STRMOVE(p, p + 1);
+
+	spell_soundfold(slang, fword, TRUE, badsound2);
+	pbad = badsound2;
+    }
+
+    if (lendiff > 0 && stp->st_wordlen + lendiff < MAXWLEN)
+    {
+	// Add part of the bad word to the good word, so that we soundfold
+	// what replaces the bad word.
+	STRCPY(goodword, stp->st_word);
+	vim_strncpy(goodword + stp->st_wordlen,
+			    su->su_badptr + su->su_badlen - lendiff, lendiff);
+	pgood = goodword;
+    }
+    else
+	pgood = stp->st_word;
+
+    // Sound-fold the word and compute the score for the difference.
+    spell_soundfold(slang, pgood, FALSE, goodsound);
+
+    return soundalike_score(goodsound, pbad);
+}
+
+// structure used to store soundfolded words that add_sound_suggest() has
+// handled already.
+typedef struct
+{
+    short	sft_score;	// lowest score used
+    char_u	sft_word[1];    // soundfolded word, actually longer
+} sftword_T;
+
+static sftword_T dumsft;
+#define HIKEY2SFT(p)  ((sftword_T *)(p - (dumsft.sft_word - (char_u *)&dumsft)))
+#define HI2SFT(hi)     HIKEY2SFT((hi)->hi_key)
+
+/*
+ * Prepare for calling suggest_try_soundalike().
+ */
+    static void
+suggest_try_soundalike_prep(void)
+{
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+
+    // Do this for all languages that support sound folding and for which a
+    // .sug file has been loaded.
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	    // prepare the hashtable used by add_sound_suggest()
+	    hash_init(&slang->sl_sounddone);
+    }
+}
+
+/*
+ * Find suggestions by comparing the word in a sound-a-like form.
+ * Note: This doesn't support postponed prefixes.
+ */
+    static void
+suggest_try_soundalike(suginfo_T *su)
+{
+    char_u	salword[MAXWLEN];
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+
+    // Do this for all languages that support sound folding and for which a
+    // .sug file has been loaded.
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	{
+	    // soundfold the bad word
+	    spell_soundfold(slang, su->su_fbadword, TRUE, salword);
+
+	    // try all kinds of inserts/deletes/swaps/etc.
+	    // TODO: also soundfold the next words, so that we can try joining
+	    // and splitting
+#ifdef SUGGEST_PROFILE
+	prof_init();
+#endif
+	    suggest_trie_walk(su, lp, salword, TRUE);
+#ifdef SUGGEST_PROFILE
+	prof_report("soundalike");
+#endif
+	}
+    }
+}
+
+/*
+ * Finish up after calling suggest_try_soundalike().
+ */
+    static void
+suggest_try_soundalike_finish(void)
+{
+    langp_T	*lp;
+    int		lpi;
+    slang_T	*slang;
+    int		todo;
+    hashitem_T	*hi;
+
+    // Do this for all languages that support sound folding and for which a
+    // .sug file has been loaded.
+    for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
+    {
+	lp = LANGP_ENTRY(curwin->w_s->b_langp, lpi);
+	slang = lp->lp_slang;
+	if (slang->sl_sal.ga_len > 0 && slang->sl_sbyts != NULL)
+	{
+	    // Free the info about handled words.
+	    todo = (int)slang->sl_sounddone.ht_used;
+	    for (hi = slang->sl_sounddone.ht_array; todo > 0; ++hi)
+		if (!HASHITEM_EMPTY(hi))
+		{
+		    vim_free(HI2SFT(hi));
+		    --todo;
+		}
+
+	    // Clear the hashtable, it may also be used by another region.
+	    hash_clear(&slang->sl_sounddone);
+	    hash_init(&slang->sl_sounddone);
+	}
+    }
+}
+
+/*
+ * A match with a soundfolded word is found.  Add the good word(s) that
+ * produce this soundfolded word.
+ */
+    static void
+add_sound_suggest(
+    suginfo_T	*su,
+    char_u	*goodword,
+    int		score,		// soundfold score
+    langp_T	*lp)
+{
+    slang_T	*slang = lp->lp_slang;	// language for sound folding
+    int		sfwordnr;
+    char_u	*nrline;
+    int		orgnr;
+    char_u	theword[MAXWLEN];
+    int		i;
+    int		wlen;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		n;
+    int		wordcount;
+    int		wc;
+    int		goodscore;
+    hash_T	hash;
+    hashitem_T  *hi;
+    sftword_T	*sft;
+    int		bc, gc;
+    int		limit;
+
+    // It's very well possible that the same soundfold word is found several
+    // times with different scores.  Since the following is quite slow only do
+    // the words that have a better score than before.  Use a hashtable to
+    // remember the words that have been done.
+    hash = hash_hash(goodword);
+    hi = hash_lookup(&slang->sl_sounddone, goodword, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	sft = alloc(sizeof(sftword_T) + STRLEN(goodword));
+	if (sft != NULL)
+	{
+	    sft->sft_score = score;
+	    STRCPY(sft->sft_word, goodword);
+	    hash_add_item(&slang->sl_sounddone, hi, sft->sft_word, hash);
+	}
+    }
+    else
+    {
+	sft = HI2SFT(hi);
+	if (score >= sft->sft_score)
+	    return;
+	sft->sft_score = score;
+    }
+
+    // Find the word nr in the soundfold tree.
+    sfwordnr = soundfold_find(slang, goodword);
+    if (sfwordnr < 0)
+    {
+	internal_error("add_sound_suggest()");
+	return;
+    }
+
+    // go over the list of good words that produce this soundfold word
+    nrline = ml_get_buf(slang->sl_sugbuf, (linenr_T)(sfwordnr + 1), FALSE);
+    orgnr = 0;
+    while (*nrline != NUL)
+    {
+	// The wordnr was stored in a minimal nr of bytes as an offset to the
+	// previous wordnr.
+	orgnr += bytes2offset(&nrline);
+
+	byts = slang->sl_fbyts;
+	idxs = slang->sl_fidxs;
+
+	// Lookup the word "orgnr" one of the two tries.
+	n = 0;
+	wordcount = 0;
+	for (wlen = 0; wlen < MAXWLEN - 3; ++wlen)
+	{
+	    i = 1;
+	    if (wordcount == orgnr && byts[n + 1] == NUL)
+		break;	// found end of word
+
+	    if (byts[n + 1] == NUL)
+		++wordcount;
+
+	    // skip over the NUL bytes
+	    for ( ; byts[n + i] == NUL; ++i)
+		if (i > byts[n])	// safety check
+		{
+		    STRCPY(theword + wlen, "BAD");
+		    wlen += 3;
+		    goto badword;
+		}
+
+	    // One of the siblings must have the word.
+	    for ( ; i < byts[n]; ++i)
+	    {
+		wc = idxs[idxs[n + i]];	// nr of words under this byte
+		if (wordcount + wc > orgnr)
+		    break;
+		wordcount += wc;
+	    }
+
+	    theword[wlen] = byts[n + i];
+	    n = idxs[n + i];
+	}
+badword:
+	theword[wlen] = NUL;
+
+	// Go over the possible flags and regions.
+	for (; i <= byts[n] && byts[n + i] == NUL; ++i)
+	{
+	    char_u	cword[MAXWLEN];
+	    char_u	*p;
+	    int		flags = (int)idxs[n + i];
+
+	    // Skip words with the NOSUGGEST flag
+	    if (flags & WF_NOSUGGEST)
+		continue;
+
+	    if (flags & WF_KEEPCAP)
+	    {
+		// Must find the word in the keep-case tree.
+		find_keepcap_word(slang, theword, cword);
+		p = cword;
+	    }
+	    else
+	    {
+		flags |= su->su_badflags;
+		if ((flags & WF_CAPMASK) != 0)
+		{
+		    // Need to fix case according to "flags".
+		    make_case_word(theword, cword, flags);
+		    p = cword;
+		}
+		else
+		    p = theword;
+	    }
+
+	    // Add the suggestion.
+	    if (sps_flags & SPS_DOUBLE)
+	    {
+		// Add the suggestion if the score isn't too bad.
+		if (score <= su->su_maxscore)
+		    add_suggestion(su, &su->su_sga, p, su->su_badlen,
+					       score, 0, FALSE, slang, FALSE);
+	    }
+	    else
+	    {
+		// Add a penalty for words in another region.
+		if ((flags & WF_REGION)
+			    && (((unsigned)flags >> 16) & lp->lp_region) == 0)
+		    goodscore = SCORE_REGION;
+		else
+		    goodscore = 0;
+
+		// Add a small penalty for changing the first letter from
+		// lower to upper case.  Helps for "tath" -> "Kath", which is
+		// less common than "tath" -> "path".  Don't do it when the
+		// letter is the same, that has already been counted.
+		gc = PTR2CHAR(p);
+		if (SPELL_ISUPPER(gc))
+		{
+		    bc = PTR2CHAR(su->su_badword);
+		    if (!SPELL_ISUPPER(bc)
+				      && SPELL_TOFOLD(bc) != SPELL_TOFOLD(gc))
+			goodscore += SCORE_ICASE / 2;
+		}
+
+		// Compute the score for the good word.  This only does letter
+		// insert/delete/swap/replace.  REP items are not considered,
+		// which may make the score a bit higher.
+		// Use a limit for the score to make it work faster.  Use
+		// MAXSCORE(), because RESCORE() will change the score.
+		// If the limit is very high then the iterative method is
+		// inefficient, using an array is quicker.
+		limit = MAXSCORE(su->su_sfmaxscore - goodscore, score);
+		if (limit > SCORE_LIMITMAX)
+		    goodscore += spell_edit_score(slang, su->su_badword, p);
+		else
+		    goodscore += spell_edit_score_limit(slang, su->su_badword,
+								    p, limit);
+
+		// When going over the limit don't bother to do the rest.
+		if (goodscore < SCORE_MAXMAX)
+		{
+		    // Give a bonus to words seen before.
+		    goodscore = score_wordcount_adj(slang, goodscore, p, FALSE);
+
+		    // Add the suggestion if the score isn't too bad.
+		    goodscore = RESCORE(goodscore, score);
+		    if (goodscore <= su->su_sfmaxscore)
+			add_suggestion(su, &su->su_ga, p, su->su_badlen,
+					 goodscore, score, TRUE, slang, TRUE);
+		}
+	    }
+	}
+	// smsg("word %s (%d): %s (%d)", sftword, sftnr, theword, orgnr);
+    }
+}
+
+/*
+ * Find word "word" in fold-case tree for "slang" and return the word number.
+ */
+    static int
+soundfold_find(slang_T *slang, char_u *word)
+{
+    idx_T	arridx = 0;
+    int		len;
+    int		wlen = 0;
+    int		c;
+    char_u	*ptr = word;
+    char_u	*byts;
+    idx_T	*idxs;
+    int		wordnr = 0;
+
+    byts = slang->sl_sbyts;
+    idxs = slang->sl_sidxs;
+
+    for (;;)
+    {
+	// First byte is the number of possible bytes.
+	len = byts[arridx++];
+
+	// If the first possible byte is a zero the word could end here.
+	// If the word ends we found the word.  If not skip the NUL bytes.
+	c = ptr[wlen];
+	if (byts[arridx] == NUL)
+	{
+	    if (c == NUL)
+		break;
+
+	    // Skip over the zeros, there can be several.
+	    while (len > 0 && byts[arridx] == NUL)
+	    {
+		++arridx;
+		--len;
+	    }
+	    if (len == 0)
+		return -1;    // no children, word should have ended here
+	    ++wordnr;
+	}
+
+	// If the word ends we didn't find it.
+	if (c == NUL)
+	    return -1;
+
+	// Perform a binary search in the list of accepted bytes.
+	if (c == TAB)	    // <Tab> is handled like <Space>
+	    c = ' ';
+	while (byts[arridx] < c)
+	{
+	    // The word count is in the first idxs[] entry of the child.
+	    wordnr += idxs[idxs[arridx]];
+	    ++arridx;
+	    if (--len == 0)	// end of the bytes, didn't find it
+		return -1;
+	}
+	if (byts[arridx] != c)	// didn't find the byte
+	    return -1;
+
+	// Continue at the child (if there is one).
+	arridx = idxs[arridx];
+	++wlen;
+
+	// One space in the good word may stand for several spaces in the
+	// checked word.
+	if (c == ' ')
+	    while (ptr[wlen] == ' ' || ptr[wlen] == TAB)
+		++wlen;
+    }
+
+    return wordnr;
+}
+
+/*
+ * Return TRUE if "c1" and "c2" are similar characters according to the MAP
+ * lines in the .aff file.
+ */
+    static int
+similar_chars(slang_T *slang, int c1, int c2)
+{
+    int		m1, m2;
+    char_u	buf[MB_MAXBYTES + 1];
+    hashitem_T  *hi;
+
+    if (c1 >= 256)
+    {
+	buf[mb_char2bytes(c1, buf)] = 0;
+	hi = hash_find(&slang->sl_map_hash, buf);
+	if (HASHITEM_EMPTY(hi))
+	    m1 = 0;
+	else
+	    m1 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+    }
+    else
+	m1 = slang->sl_map_array[c1];
+    if (m1 == 0)
+	return FALSE;
+
+
+    if (c2 >= 256)
+    {
+	buf[mb_char2bytes(c2, buf)] = 0;
+	hi = hash_find(&slang->sl_map_hash, buf);
+	if (HASHITEM_EMPTY(hi))
+	    m2 = 0;
+	else
+	    m2 = mb_ptr2char(hi->hi_key + STRLEN(hi->hi_key) + 1);
+    }
+    else
+	m2 = slang->sl_map_array[c2];
+
+    return m1 == m2;
+}
+
+/*
+ * Add a suggestion to the list of suggestions.
+ * For a suggestion that is already in the list the lowest score is remembered.
+ */
+    static void
+add_suggestion(
+    suginfo_T	*su,
+    garray_T	*gap,		// either su_ga or su_sga
+    char_u	*goodword,
+    int		badlenarg,	// len of bad word replaced with "goodword"
+    int		score,
+    int		altscore,
+    int		had_bonus,	// value for st_had_bonus
+    slang_T	*slang,		// language for sound folding
+    int		maxsf)		// su_maxscore applies to soundfold score,
+				// su_sfmaxscore to the total score.
+{
+    int		goodlen;	// len of goodword changed
+    int		badlen;		// len of bad word changed
+    suggest_T   *stp;
+    suggest_T   new_sug;
+    int		i;
+    char_u	*pgood, *pbad;
+
+    // Minimize "badlen" for consistency.  Avoids that changing "the the" to
+    // "thee the" is added next to changing the first "the" the "thee".
+    pgood = goodword + STRLEN(goodword);
+    pbad = su->su_badptr + badlenarg;
+    for (;;)
+    {
+	goodlen = (int)(pgood - goodword);
+	badlen = (int)(pbad - su->su_badptr);
+	if (goodlen <= 0 || badlen <= 0)
+	    break;
+	MB_PTR_BACK(goodword, pgood);
+	MB_PTR_BACK(su->su_badptr, pbad);
+	if (has_mbyte)
+	{
+	    if (mb_ptr2char(pgood) != mb_ptr2char(pbad))
+		break;
+	}
+	else if (*pgood != *pbad)
+		break;
+    }
+
+    if (badlen == 0 && goodlen == 0)
+	// goodword doesn't change anything; may happen for "the the" changing
+	// the first "the" to itself.
+	return;
+
+    if (gap->ga_len == 0)
+	i = -1;
+    else
+    {
+	// Check if the word is already there.  Also check the length that is
+	// being replaced "thes," -> "these" is a different suggestion from
+	// "thes" -> "these".
+	stp = &SUG(*gap, 0);
+	for (i = gap->ga_len; --i >= 0; ++stp)
+	    if (stp->st_wordlen == goodlen
+		    && stp->st_orglen == badlen
+		    && STRNCMP(stp->st_word, goodword, goodlen) == 0)
+	    {
+		// Found it.  Remember the word with the lowest score.
+		if (stp->st_slang == NULL)
+		    stp->st_slang = slang;
+
+		new_sug.st_score = score;
+		new_sug.st_altscore = altscore;
+		new_sug.st_had_bonus = had_bonus;
+
+		if (stp->st_had_bonus != had_bonus)
+		{
+		    // Only one of the two had the soundalike score computed.
+		    // Need to do that for the other one now, otherwise the
+		    // scores can't be compared.  This happens because
+		    // suggest_try_change() doesn't compute the soundalike
+		    // word to keep it fast, while some special methods set
+		    // the soundalike score to zero.
+		    if (had_bonus)
+			rescore_one(su, stp);
+		    else
+		    {
+			new_sug.st_word = stp->st_word;
+			new_sug.st_wordlen = stp->st_wordlen;
+			new_sug.st_slang = stp->st_slang;
+			new_sug.st_orglen = badlen;
+			rescore_one(su, &new_sug);
+		    }
+		}
+
+		if (stp->st_score > new_sug.st_score)
+		{
+		    stp->st_score = new_sug.st_score;
+		    stp->st_altscore = new_sug.st_altscore;
+		    stp->st_had_bonus = new_sug.st_had_bonus;
+		}
+		break;
+	    }
+    }
+
+    if (i < 0 && ga_grow(gap, 1) == OK)
+    {
+	// Add a suggestion.
+	stp = &SUG(*gap, gap->ga_len);
+	stp->st_word = vim_strnsave(goodword, goodlen);
+	if (stp->st_word != NULL)
+	{
+	    stp->st_wordlen = goodlen;
+	    stp->st_score = score;
+	    stp->st_altscore = altscore;
+	    stp->st_had_bonus = had_bonus;
+	    stp->st_orglen = badlen;
+	    stp->st_slang = slang;
+	    ++gap->ga_len;
+
+	    // If we have too many suggestions now, sort the list and keep
+	    // the best suggestions.
+	    if (gap->ga_len > SUG_MAX_COUNT(su))
+	    {
+		if (maxsf)
+		    su->su_sfmaxscore = cleanup_suggestions(gap,
+				      su->su_sfmaxscore, SUG_CLEAN_COUNT(su));
+		else
+		    su->su_maxscore = cleanup_suggestions(gap,
+					su->su_maxscore, SUG_CLEAN_COUNT(su));
+	    }
+	}
+    }
+}
+
+/*
+ * Suggestions may in fact be flagged as errors.  Esp. for banned words and
+ * for split words, such as "the the".  Remove these from the list here.
+ */
+    static void
+check_suggestions(
+    suginfo_T	*su,
+    garray_T	*gap)		    // either su_ga or su_sga
+{
+    suggest_T   *stp;
+    int		i;
+    char_u	longword[MAXWLEN + 1];
+    int		len;
+    hlf_T	attr;
+
+    stp = &SUG(*gap, 0);
+    for (i = gap->ga_len - 1; i >= 0; --i)
+    {
+	// Need to append what follows to check for "the the".
+	vim_strncpy(longword, stp[i].st_word, MAXWLEN);
+	len = stp[i].st_wordlen;
+	vim_strncpy(longword + len, su->su_badptr + stp[i].st_orglen,
+							       MAXWLEN - len);
+	attr = HLF_COUNT;
+	(void)spell_check(curwin, longword, &attr, NULL, FALSE);
+	if (attr != HLF_COUNT)
+	{
+	    // Remove this entry.
+	    vim_free(stp[i].st_word);
+	    --gap->ga_len;
+	    if (i < gap->ga_len)
+		mch_memmove(stp + i, stp + i + 1,
+				       sizeof(suggest_T) * (gap->ga_len - i));
+	}
+    }
+}
+
+
+/*
+ * Add a word to be banned.
+ */
+    static void
+add_banned(
+    suginfo_T	*su,
+    char_u	*word)
+{
+    char_u	*s;
+    hash_T	hash;
+    hashitem_T	*hi;
+
+    hash = hash_hash(word);
+    hi = hash_lookup(&su->su_banned, word, hash);
+    if (HASHITEM_EMPTY(hi))
+    {
+	s = vim_strsave(word);
+	if (s != NULL)
+	    hash_add_item(&su->su_banned, hi, s, hash);
+    }
+}
+
+/*
+ * Recompute the score for all suggestions if sound-folding is possible.  This
+ * is slow, thus only done for the final results.
+ */
+    static void
+rescore_suggestions(suginfo_T *su)
+{
+    int		i;
+
+    if (su->su_sallang != NULL)
+	for (i = 0; i < su->su_ga.ga_len; ++i)
+	    rescore_one(su, &SUG(su->su_ga, i));
+}
+
+/*
+ * Recompute the score for one suggestion if sound-folding is possible.
+ */
+    static void
+rescore_one(suginfo_T *su, suggest_T *stp)
+{
+    slang_T	*slang = stp->st_slang;
+    char_u	sal_badword[MAXWLEN];
+    char_u	*p;
+
+    // Only rescore suggestions that have no sal score yet and do have a
+    // language.
+    if (slang != NULL && slang->sl_sal.ga_len > 0 && !stp->st_had_bonus)
+    {
+	if (slang == su->su_sallang)
+	    p = su->su_sal_badword;
+	else
+	{
+	    spell_soundfold(slang, su->su_fbadword, TRUE, sal_badword);
+	    p = sal_badword;
+	}
+
+	stp->st_altscore = stp_sal_score(stp, su, slang, p);
+	if (stp->st_altscore == SCORE_MAXMAX)
+	    stp->st_altscore = SCORE_BIG;
+	stp->st_score = RESCORE(stp->st_score, stp->st_altscore);
+	stp->st_had_bonus = TRUE;
+    }
+}
+
+static int sug_compare(const void *s1, const void *s2);
+
+/*
+ * Function given to qsort() to sort the suggestions on st_score.
+ * First on "st_score", then "st_altscore" then alphabetically.
+ */
+    static int
+sug_compare(const void *s1, const void *s2)
+{
+    suggest_T	*p1 = (suggest_T *)s1;
+    suggest_T	*p2 = (suggest_T *)s2;
+    int		n = p1->st_score - p2->st_score;
+
+    if (n == 0)
+    {
+	n = p1->st_altscore - p2->st_altscore;
+	if (n == 0)
+	    n = STRICMP(p1->st_word, p2->st_word);
+    }
+    return n;
+}
+
+/*
+ * Cleanup the suggestions:
+ * - Sort on score.
+ * - Remove words that won't be displayed.
+ * Returns the maximum score in the list or "maxscore" unmodified.
+ */
+    static int
+cleanup_suggestions(
+    garray_T	*gap,
+    int		maxscore,
+    int		keep)		// nr of suggestions to keep
+{
+    suggest_T   *stp = &SUG(*gap, 0);
+    int		i;
+
+    // Sort the list.
+    qsort(gap->ga_data, (size_t)gap->ga_len, sizeof(suggest_T), sug_compare);
+
+    // Truncate the list to the number of suggestions that will be displayed.
+    if (gap->ga_len > keep)
+    {
+	for (i = keep; i < gap->ga_len; ++i)
+	    vim_free(stp[i].st_word);
+	gap->ga_len = keep;
+	return stp[keep - 1].st_score;
+    }
+    return maxscore;
+}
+
+/*
+ * Compute a score for two sound-a-like words.
+ * This permits up to two inserts/deletes/swaps/etc. to keep things fast.
+ * Instead of a generic loop we write out the code.  That keeps it fast by
+ * avoiding checks that will not be possible.
+ */
+    static int
+soundalike_score(
+    char_u	*goodstart,	// sound-folded good word
+    char_u	*badstart)	// sound-folded bad word
+{
+    char_u	*goodsound = goodstart;
+    char_u	*badsound = badstart;
+    int		goodlen;
+    int		badlen;
+    int		n;
+    char_u	*pl, *ps;
+    char_u	*pl2, *ps2;
+    int		score = 0;
+
+    // Adding/inserting "*" at the start (word starts with vowel) shouldn't be
+    // counted so much, vowels halfway the word aren't counted at all.
+    if ((*badsound == '*' || *goodsound == '*') && *badsound != *goodsound)
+    {
+	if ((badsound[0] == NUL && goodsound[1] == NUL)
+	    || (goodsound[0] == NUL && badsound[1] == NUL))
+	    // changing word with vowel to word without a sound
+	    return SCORE_DEL;
+	if (badsound[0] == NUL || goodsound[0] == NUL)
+	    // more than two changes
+	    return SCORE_MAXMAX;
+
+	if (badsound[1] == goodsound[1]
+		|| (badsound[1] != NUL
+		    && goodsound[1] != NUL
+		    && badsound[2] == goodsound[2]))
+	{
+	    // handle like a substitute
+	}
+	else
+	{
+	    score = 2 * SCORE_DEL / 3;
+	    if (*badsound == '*')
+		++badsound;
+	    else
+		++goodsound;
+	}
+    }
+
+    goodlen = (int)STRLEN(goodsound);
+    badlen = (int)STRLEN(badsound);
+
+    // Return quickly if the lengths are too different to be fixed by two
+    // changes.
+    n = goodlen - badlen;
+    if (n < -2 || n > 2)
+	return SCORE_MAXMAX;
+
+    if (n > 0)
+    {
+	pl = goodsound;	    // goodsound is longest
+	ps = badsound;
+    }
+    else
+    {
+	pl = badsound;	    // badsound is longest
+	ps = goodsound;
+    }
+
+    // Skip over the identical part.
+    while (*pl == *ps && *pl != NUL)
+    {
+	++pl;
+	++ps;
+    }
+
+    switch (n)
+    {
+	case -2:
+	case 2:
+	    // Must delete two characters from "pl".
+	    ++pl;	// first delete
+	    while (*pl == *ps)
+	    {
+		++pl;
+		++ps;
+	    }
+	    // strings must be equal after second delete
+	    if (STRCMP(pl + 1, ps) == 0)
+		return score + SCORE_DEL * 2;
+
+	    // Failed to compare.
+	    break;
+
+	case -1:
+	case 1:
+	    // Minimal one delete from "pl" required.
+
+	    // 1: delete
+	    pl2 = pl + 1;
+	    ps2 = ps;
+	    while (*pl2 == *ps2)
+	    {
+		if (*pl2 == NUL)	// reached the end
+		    return score + SCORE_DEL;
+		++pl2;
+		++ps2;
+	    }
+
+	    // 2: delete then swap, then rest must be equal
+	    if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		return score + SCORE_DEL + SCORE_SWAP;
+
+	    // 3: delete then substitute, then the rest must be equal
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return score + SCORE_DEL + SCORE_SUBST;
+
+	    // 4: first swap then delete
+	    if (pl[0] == ps[1] && pl[1] == ps[0])
+	    {
+		pl2 = pl + 2;	    // swap, skip two chars
+		ps2 = ps + 2;
+		while (*pl2 == *ps2)
+		{
+		    ++pl2;
+		    ++ps2;
+		}
+		// delete a char and then strings must be equal
+		if (STRCMP(pl2 + 1, ps2) == 0)
+		    return score + SCORE_SWAP + SCORE_DEL;
+	    }
+
+	    // 5: first substitute then delete
+	    pl2 = pl + 1;	    // substitute, skip one char
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    // delete a char and then strings must be equal
+	    if (STRCMP(pl2 + 1, ps2) == 0)
+		return score + SCORE_SUBST + SCORE_DEL;
+
+	    // Failed to compare.
+	    break;
+
+	case 0:
+	    // Lengths are equal, thus changes must result in same length: An
+	    // insert is only possible in combination with a delete.
+	    // 1: check if for identical strings
+	    if (*pl == NUL)
+		return score;
+
+	    // 2: swap
+	    if (pl[0] == ps[1] && pl[1] == ps[0])
+	    {
+		pl2 = pl + 2;	    // swap, skip two chars
+		ps2 = ps + 2;
+		while (*pl2 == *ps2)
+		{
+		    if (*pl2 == NUL)	// reached the end
+			return score + SCORE_SWAP;
+		    ++pl2;
+		    ++ps2;
+		}
+		// 3: swap and swap again
+		if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		    return score + SCORE_SWAP + SCORE_SWAP;
+
+		// 4: swap and substitute
+		if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		    return score + SCORE_SWAP + SCORE_SUBST;
+	    }
+
+	    // 5: substitute
+	    pl2 = pl + 1;
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		if (*pl2 == NUL)	// reached the end
+		    return score + SCORE_SUBST;
+		++pl2;
+		++ps2;
+	    }
+
+	    // 6: substitute and swap
+	    if (pl2[0] == ps2[1] && pl2[1] == ps2[0]
+					     && STRCMP(pl2 + 2, ps2 + 2) == 0)
+		return score + SCORE_SUBST + SCORE_SWAP;
+
+	    // 7: substitute and substitute
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return score + SCORE_SUBST + SCORE_SUBST;
+
+	    // 8: insert then delete
+	    pl2 = pl;
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    if (STRCMP(pl2 + 1, ps2) == 0)
+		return score + SCORE_INS + SCORE_DEL;
+
+	    // 9: delete then insert
+	    pl2 = pl + 1;
+	    ps2 = ps;
+	    while (*pl2 == *ps2)
+	    {
+		++pl2;
+		++ps2;
+	    }
+	    if (STRCMP(pl2, ps2 + 1) == 0)
+		return score + SCORE_INS + SCORE_DEL;
+
+	    // Failed to compare.
+	    break;
+    }
+
+    return SCORE_MAXMAX;
+}
+
+/*
+ * Compute the "edit distance" to turn "badword" into "goodword".  The less
+ * deletes/inserts/substitutes/swaps are required the lower the score.
+ *
+ * The algorithm is described by Du and Chang, 1992.
+ * The implementation of the algorithm comes from Aspell editdist.cpp,
+ * edit_distance().  It has been converted from C++ to C and modified to
+ * support multi-byte characters.
+ */
+    static int
+spell_edit_score(
+    slang_T	*slang,
+    char_u	*badword,
+    char_u	*goodword)
+{
+    int		*cnt;
+    int		badlen, goodlen;	// lengths including NUL
+    int		j, i;
+    int		t;
+    int		bc, gc;
+    int		pbc, pgc;
+    char_u	*p;
+    int		wbadword[MAXWLEN];
+    int		wgoodword[MAXWLEN];
+
+    if (has_mbyte)
+    {
+	// Get the characters from the multi-byte strings and put them in an
+	// int array for easy access.
+	for (p = badword, badlen = 0; *p != NUL; )
+	    wbadword[badlen++] = mb_cptr2char_adv(&p);
+	wbadword[badlen++] = 0;
+	for (p = goodword, goodlen = 0; *p != NUL; )
+	    wgoodword[goodlen++] = mb_cptr2char_adv(&p);
+	wgoodword[goodlen++] = 0;
+    }
+    else
+    {
+	badlen = (int)STRLEN(badword) + 1;
+	goodlen = (int)STRLEN(goodword) + 1;
+    }
+
+    // We use "cnt" as an array: CNT(badword_idx, goodword_idx).
+#define CNT(a, b)   cnt[(a) + (b) * (badlen + 1)]
+    cnt = ALLOC_MULT(int, (badlen + 1) * (goodlen + 1));
+    if (cnt == NULL)
+	return 0;	// out of memory
+
+    CNT(0, 0) = 0;
+    for (j = 1; j <= goodlen; ++j)
+	CNT(0, j) = CNT(0, j - 1) + SCORE_INS;
+
+    for (i = 1; i <= badlen; ++i)
+    {
+	CNT(i, 0) = CNT(i - 1, 0) + SCORE_DEL;
+	for (j = 1; j <= goodlen; ++j)
+	{
+	    if (has_mbyte)
+	    {
+		bc = wbadword[i - 1];
+		gc = wgoodword[j - 1];
+	    }
+	    else
+	    {
+		bc = badword[i - 1];
+		gc = goodword[j - 1];
+	    }
+	    if (bc == gc)
+		CNT(i, j) = CNT(i - 1, j - 1);
+	    else
+	    {
+		// Use a better score when there is only a case difference.
+		if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		    CNT(i, j) = SCORE_ICASE + CNT(i - 1, j - 1);
+		else
+		{
+		    // For a similar character use SCORE_SIMILAR.
+		    if (slang != NULL
+			    && slang->sl_has_map
+			    && similar_chars(slang, gc, bc))
+			CNT(i, j) = SCORE_SIMILAR + CNT(i - 1, j - 1);
+		    else
+			CNT(i, j) = SCORE_SUBST + CNT(i - 1, j - 1);
+		}
+
+		if (i > 1 && j > 1)
+		{
+		    if (has_mbyte)
+		    {
+			pbc = wbadword[i - 2];
+			pgc = wgoodword[j - 2];
+		    }
+		    else
+		    {
+			pbc = badword[i - 2];
+			pgc = goodword[j - 2];
+		    }
+		    if (bc == pgc && pbc == gc)
+		    {
+			t = SCORE_SWAP + CNT(i - 2, j - 2);
+			if (t < CNT(i, j))
+			    CNT(i, j) = t;
+		    }
+		}
+		t = SCORE_DEL + CNT(i - 1, j);
+		if (t < CNT(i, j))
+		    CNT(i, j) = t;
+		t = SCORE_INS + CNT(i, j - 1);
+		if (t < CNT(i, j))
+		    CNT(i, j) = t;
+	    }
+	}
+    }
+
+    i = CNT(badlen - 1, goodlen - 1);
+    vim_free(cnt);
+    return i;
+}
+
+typedef struct
+{
+    int		badi;
+    int		goodi;
+    int		score;
+} limitscore_T;
+
+/*
+ * Like spell_edit_score(), but with a limit on the score to make it faster.
+ * May return SCORE_MAXMAX when the score is higher than "limit".
+ *
+ * This uses a stack for the edits still to be tried.
+ * The idea comes from Aspell leditdist.cpp.  Rewritten in C and added support
+ * for multi-byte characters.
+ */
+    static int
+spell_edit_score_limit(
+    slang_T	*slang,
+    char_u	*badword,
+    char_u	*goodword,
+    int		limit)
+{
+    limitscore_T    stack[10];		// allow for over 3 * 2 edits
+    int		    stackidx;
+    int		    bi, gi;
+    int		    bi2, gi2;
+    int		    bc, gc;
+    int		    score;
+    int		    score_off;
+    int		    minscore;
+    int		    round;
+
+    // Multi-byte characters require a bit more work, use a different function
+    // to avoid testing "has_mbyte" quite often.
+    if (has_mbyte)
+	return spell_edit_score_limit_w(slang, badword, goodword, limit);
+
+    // The idea is to go from start to end over the words.  So long as
+    // characters are equal just continue, this always gives the lowest score.
+    // When there is a difference try several alternatives.  Each alternative
+    // increases "score" for the edit distance.  Some of the alternatives are
+    // pushed unto a stack and tried later, some are tried right away.  At the
+    // end of the word the score for one alternative is known.  The lowest
+    // possible score is stored in "minscore".
+    stackidx = 0;
+    bi = 0;
+    gi = 0;
+    score = 0;
+    minscore = limit + 1;
+
+    for (;;)
+    {
+	// Skip over an equal part, score remains the same.
+	for (;;)
+	{
+	    bc = badword[bi];
+	    gc = goodword[gi];
+	    if (bc != gc)	// stop at a char that's different
+		break;
+	    if (bc == NUL)	// both words end
+	    {
+		if (score < minscore)
+		    minscore = score;
+		goto pop;	// do next alternative
+	    }
+	    ++bi;
+	    ++gi;
+	}
+
+	if (gc == NUL)    // goodword ends, delete badword chars
+	{
+	    do
+	    {
+		if ((score += SCORE_DEL) >= minscore)
+		    goto pop;	    // do next alternative
+	    } while (badword[++bi] != NUL);
+	    minscore = score;
+	}
+	else if (bc == NUL) // badword ends, insert badword chars
+	{
+	    do
+	    {
+		if ((score += SCORE_INS) >= minscore)
+		    goto pop;	    // do next alternative
+	    } while (goodword[++gi] != NUL);
+	    minscore = score;
+	}
+	else			// both words continue
+	{
+	    // If not close to the limit, perform a change.  Only try changes
+	    // that may lead to a lower score than "minscore".
+	    // round 0: try deleting a char from badword
+	    // round 1: try inserting a char in badword
+	    for (round = 0; round <= 1; ++round)
+	    {
+		score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+		if (score_off < minscore)
+		{
+		    if (score_off + SCORE_EDIT_MIN >= minscore)
+		    {
+			// Near the limit, rest of the words must match.  We
+			// can check that right now, no need to push an item
+			// onto the stack.
+			bi2 = bi + 1 - round;
+			gi2 = gi + round;
+			while (goodword[gi2] == badword[bi2])
+			{
+			    if (goodword[gi2] == NUL)
+			    {
+				minscore = score_off;
+				break;
+			    }
+			    ++bi2;
+			    ++gi2;
+			}
+		    }
+		    else
+		    {
+			// try deleting/inserting a character later
+			stack[stackidx].badi = bi + 1 - round;
+			stack[stackidx].goodi = gi + round;
+			stack[stackidx].score = score_off;
+			++stackidx;
+		    }
+		}
+	    }
+
+	    if (score + SCORE_SWAP < minscore)
+	    {
+		// If swapping two characters makes a match then the
+		// substitution is more expensive, thus there is no need to
+		// try both.
+		if (gc == badword[bi + 1] && bc == goodword[gi + 1])
+		{
+		    // Swap two characters, that is: skip them.
+		    gi += 2;
+		    bi += 2;
+		    score += SCORE_SWAP;
+		    continue;
+		}
+	    }
+
+	    // Substitute one character for another which is the same
+	    // thing as deleting a character from both goodword and badword.
+	    // Use a better score when there is only a case difference.
+	    if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		score += SCORE_ICASE;
+	    else
+	    {
+		// For a similar character use SCORE_SIMILAR.
+		if (slang != NULL
+			&& slang->sl_has_map
+			&& similar_chars(slang, gc, bc))
+		    score += SCORE_SIMILAR;
+		else
+		    score += SCORE_SUBST;
+	    }
+
+	    if (score < minscore)
+	    {
+		// Do the substitution.
+		++gi;
+		++bi;
+		continue;
+	    }
+	}
+pop:
+	// Get here to try the next alternative, pop it from the stack.
+	if (stackidx == 0)		// stack is empty, finished
+	    break;
+
+	// pop an item from the stack
+	--stackidx;
+	gi = stack[stackidx].goodi;
+	bi = stack[stackidx].badi;
+	score = stack[stackidx].score;
+    }
+
+    // When the score goes over "limit" it may actually be much higher.
+    // Return a very large number to avoid going below the limit when giving a
+    // bonus.
+    if (minscore > limit)
+	return SCORE_MAXMAX;
+    return minscore;
+}
+
+/*
+ * Multi-byte version of spell_edit_score_limit().
+ * Keep it in sync with the above!
+ */
+    static int
+spell_edit_score_limit_w(
+    slang_T	*slang,
+    char_u	*badword,
+    char_u	*goodword,
+    int		limit)
+{
+    limitscore_T    stack[10];		// allow for over 3 * 2 edits
+    int		    stackidx;
+    int		    bi, gi;
+    int		    bi2, gi2;
+    int		    bc, gc;
+    int		    score;
+    int		    score_off;
+    int		    minscore;
+    int		    round;
+    char_u	    *p;
+    int		    wbadword[MAXWLEN];
+    int		    wgoodword[MAXWLEN];
+
+    // Get the characters from the multi-byte strings and put them in an
+    // int array for easy access.
+    bi = 0;
+    for (p = badword; *p != NUL; )
+	wbadword[bi++] = mb_cptr2char_adv(&p);
+    wbadword[bi++] = 0;
+    gi = 0;
+    for (p = goodword; *p != NUL; )
+	wgoodword[gi++] = mb_cptr2char_adv(&p);
+    wgoodword[gi++] = 0;
+
+    // The idea is to go from start to end over the words.  So long as
+    // characters are equal just continue, this always gives the lowest score.
+    // When there is a difference try several alternatives.  Each alternative
+    // increases "score" for the edit distance.  Some of the alternatives are
+    // pushed unto a stack and tried later, some are tried right away.  At the
+    // end of the word the score for one alternative is known.  The lowest
+    // possible score is stored in "minscore".
+    stackidx = 0;
+    bi = 0;
+    gi = 0;
+    score = 0;
+    minscore = limit + 1;
+
+    for (;;)
+    {
+	// Skip over an equal part, score remains the same.
+	for (;;)
+	{
+	    bc = wbadword[bi];
+	    gc = wgoodword[gi];
+
+	    if (bc != gc)	// stop at a char that's different
+		break;
+	    if (bc == NUL)	// both words end
+	    {
+		if (score < minscore)
+		    minscore = score;
+		goto pop;	// do next alternative
+	    }
+	    ++bi;
+	    ++gi;
+	}
+
+	if (gc == NUL)    // goodword ends, delete badword chars
+	{
+	    do
+	    {
+		if ((score += SCORE_DEL) >= minscore)
+		    goto pop;	    // do next alternative
+	    } while (wbadword[++bi] != NUL);
+	    minscore = score;
+	}
+	else if (bc == NUL) // badword ends, insert badword chars
+	{
+	    do
+	    {
+		if ((score += SCORE_INS) >= minscore)
+		    goto pop;	    // do next alternative
+	    } while (wgoodword[++gi] != NUL);
+	    minscore = score;
+	}
+	else			// both words continue
+	{
+	    // If not close to the limit, perform a change.  Only try changes
+	    // that may lead to a lower score than "minscore".
+	    // round 0: try deleting a char from badword
+	    // round 1: try inserting a char in badword
+	    for (round = 0; round <= 1; ++round)
+	    {
+		score_off = score + (round == 0 ? SCORE_DEL : SCORE_INS);
+		if (score_off < minscore)
+		{
+		    if (score_off + SCORE_EDIT_MIN >= minscore)
+		    {
+			// Near the limit, rest of the words must match.  We
+			// can check that right now, no need to push an item
+			// onto the stack.
+			bi2 = bi + 1 - round;
+			gi2 = gi + round;
+			while (wgoodword[gi2] == wbadword[bi2])
+			{
+			    if (wgoodword[gi2] == NUL)
+			    {
+				minscore = score_off;
+				break;
+			    }
+			    ++bi2;
+			    ++gi2;
+			}
+		    }
+		    else
+		    {
+			// try deleting a character from badword later
+			stack[stackidx].badi = bi + 1 - round;
+			stack[stackidx].goodi = gi + round;
+			stack[stackidx].score = score_off;
+			++stackidx;
+		    }
+		}
+	    }
+
+	    if (score + SCORE_SWAP < minscore)
+	    {
+		// If swapping two characters makes a match then the
+		// substitution is more expensive, thus there is no need to
+		// try both.
+		if (gc == wbadword[bi + 1] && bc == wgoodword[gi + 1])
+		{
+		    // Swap two characters, that is: skip them.
+		    gi += 2;
+		    bi += 2;
+		    score += SCORE_SWAP;
+		    continue;
+		}
+	    }
+
+	    // Substitute one character for another which is the same
+	    // thing as deleting a character from both goodword and badword.
+	    // Use a better score when there is only a case difference.
+	    if (SPELL_TOFOLD(bc) == SPELL_TOFOLD(gc))
+		score += SCORE_ICASE;
+	    else
+	    {
+		// For a similar character use SCORE_SIMILAR.
+		if (slang != NULL
+			&& slang->sl_has_map
+			&& similar_chars(slang, gc, bc))
+		    score += SCORE_SIMILAR;
+		else
+		    score += SCORE_SUBST;
+	    }
+
+	    if (score < minscore)
+	    {
+		// Do the substitution.
+		++gi;
+		++bi;
+		continue;
+	    }
+	}
+pop:
+	// Get here to try the next alternative, pop it from the stack.
+	if (stackidx == 0)		// stack is empty, finished
+	    break;
+
+	// pop an item from the stack
+	--stackidx;
+	gi = stack[stackidx].goodi;
+	bi = stack[stackidx].badi;
+	score = stack[stackidx].score;
+    }
+
+    // When the score goes over "limit" it may actually be much higher.
+    // Return a very large number to avoid going below the limit when giving a
+    // bonus.
+    if (minscore > limit)
+	return SCORE_MAXMAX;
+    return minscore;
+}
+#endif  // FEAT_SPELL
