updated for version 7.0089
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index aba12a1..83f81ad 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jun 17
+*eval.txt*      For Vim version 7.0aa.  Last change: 2005 Jun 20
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1603,6 +1603,8 @@
 setwinvar( {nr}, {varname}, {val})	set {varname} in window {nr} to {val}
 simplify( {filename})		String	simplify filename as much as possible
 sort( {list} [, {func}])	List	sort {list}, using {func} to compare
+spellbadword()			String	badly spelled word at cursor
+spellsuggest({word} [, {max}])	List	spelling suggestions
 split( {expr} [, {pat} [, {keepempty}]])
 				List	make List from {pat} separated {expr}
 strftime( {format}[, {time}])	String	time in specified format
@@ -3757,6 +3759,27 @@
 			   return a:i1 == a:i2 ? 0 : a:i1 > a:i2 ? 1 : -1
 			endfunc
 			let sortedlist = sort(mylist, "MyCompare")
+<
+
+							*spellbadword()*
+spellbadword()	Return the badly spelled word under or after the cursor.
+		The cursor is advanced to the start of the bad word.
+		When no bad word is found in the cursor line an empty String
+		is returned and the cursor doesn't move.
+
+							*spellsuggest()*
+spellsuggest({word} [, {max}])
+		Return a List with spelling suggestions to replace {word}.
+		When {max} is given up to this number of suggestions are
+		returned.  Otherwise up to 25 suggestions are returned.
+
+		{word} can be a badly spelled word followed by other text.
+		This allows for joining two words that were split.  The
+		suggestions then also include the following text.
+
+		The spelling information for the current window is used.  The
+		'spell' option must be set and 'spelllang' is relevant.
+
 
 split({expr} [, {pattern} [, {keepempty}]])			*split()*
 		Make a List out of {expr}.  When {pattern} is omitted or empty
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 94bd9f4..a2c05f9 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jun 17
+*options.txt*	For Vim version 7.0aa.  Last change: 2005 Jun 21
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -5662,6 +5662,25 @@
 	idea to set 'spelllang' after setting 'encoding'.
 	More info at |spell|.
 
+						*'spellsuggest'* *'sps'*
+'spellsuggest' 'sps'	string	(default "best")
+			global
+			{not in Vi}
+			{not available when compiled without the |+syntax|
+			feature}
+	Method used for spelling suggestions |z?|.  Can be one of these
+	values:
+
+	best		Method that works best for English.  Finds small
+			changes and uses some sound-a-like scoring.
+	double		Uses two methods and mixes the results.  The first
+			method is finding small changes, the other method
+			computes how much the suggestion sounds like the bad
+			word.  Can be slow and doesn't always give better
+			results.
+	fast		Only check for small changes.
+
+
 			*'splitbelow'* *'sb'* *'nosplitbelow'* *'nosb'*
 'splitbelow' 'sb'	boolean	(default off)
 			global
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index 4c7a1a8..7013e6d 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -1,4 +1,4 @@
-*spell.txt*	For Vim version 7.0aa.  Last change: 2005 Jun 19
+*spell.txt*	For Vim version 7.0aa.  Last change: 2005 Jun 21
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -92,6 +92,12 @@
 			higher the score the more different).
 			The score may be slightly wrong for words with
 			multi-byte characters.
+			When a word was replaced the redo command "." will
+			repeat the word replacement.  This works like "ciw",
+			the good word and <Esc>.
+
+The 'spellsuggest' option influences how the list of suggestions is generated
+and sorted.  See |'spellsuggest'|.
 
 
 PERFORMANCE
@@ -337,7 +343,7 @@
 	/regions=uscagb				regions "us", "ca" and "gb"
 	example					word for all regions
 	/1blah					word for region 1 "us"
-	/!Vim					bad word
+	/!vim					bad word
 	/?3Campbell				rare word in region 3 "gb"
 	/='s mornings				keep-case word
 
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 7ec2e28..ce4807a 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -5130,6 +5130,7 @@
 hebrew.txt	hebrew.txt	/*hebrew.txt*
 help	various.txt	/*help*
 help-context	help.txt	/*help-context*
+help-tags	tags	1
 help-translated	various.txt	/*help-translated*
 help-xterm-window	various.txt	/*help-xterm-window*
 help.txt	help.txt	/*help.txt*
@@ -6274,6 +6275,8 @@
 spell-syntax	spell.txt	/*spell-syntax*
 spell-wordlist-format	spell.txt	/*spell-wordlist-format*
 spell.txt	spell.txt	/*spell.txt*
+spellbadword()	eval.txt	/*spellbadword()*
+spellsuggest()	eval.txt	/*spellsuggest()*
 split()	eval.txt	/*split()*
 splitfind	windows.txt	/*splitfind*
 splitview	windows.txt	/*splitview*
diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt
index 06a8fbc..6159b8f 100644
--- a/runtime/doc/todo.txt
+++ b/runtime/doc/todo.txt
@@ -1,4 +1,4 @@
-*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jun 19
+*todo.txt*      For Vim version 7.0aa.  Last change: 2005 Jun 22
 
 
 		  VIM REFERENCE MANUAL	  by Bram Moolenaar
@@ -30,9 +30,6 @@
 							*known-bugs*
 -------------------- Known bugs and current work -----------------------
 
-Can define a function with illegal name (Servatius Brandt):
-    function F{-1}()
-
 Add extra list of file locations.  Can be used with:
     :ltag	      list of matching tags, like :tselect
 
@@ -56,6 +53,8 @@
     Patch from Sergey Khorev, 2005 Apr 11
     Add has("balloon_multiline")
 
+Win32: Crash when pasting Simplified Chinese in utf-8. (rainux, 2005 June 20)
+
 Mac unicode patch (Da Woon Jung):
 - selecting proportional font breaks display
 - UTF-8 text causes display problems.  Font replacement causes this.
@@ -100,14 +99,22 @@
 -   Add SPELLCHECKER, with support for many languages.
     - Spell checking code todo's:
 	- Code for making suggestions:
-	  - Hebrew: also use prefixes for suggestions.
+	  - ":mkspell" runs out of memory for Polish with utf-8.
 	  - When 'spellfile' directory doesn't exist, ask user to create it?
+	  - When 'spelllang' has more than one language only .add file of
+	    first is used?
 	  - Aspell has the "special" character, useful?
+	  - Can "the the" be added as a bad word?
+		Add BAD item in .aff file, set WF_BANNED flag.
+	  - Simple and fast sound-a-like: mapping list for first char and rest
+		    vowel as first char: *
+		    remove other vowels
+	  - How about words that are split over two lines?  E.g., "et al.".
 	  - When putting map string in .spl file check for duplicate chars.
-	  - GUI: Selecting text doesn't work at the prompt.
-	  - Should "z?" replacement be redo-able with "."?
+	  - Hebrew: also use prefixes for suggestions.  See message from
+	    Kaminsky (June 20) for ideas.
 	  - The sound-folding doesn't work for multi-byte characters.  It's
-	    very slow too.  Prepare the table (remove alternatives)?
+	    very slow too.
 	- Also put list of word characters in word list file.  Otherwise the
 	  one for Italian may differ from the one used for English.
 	- Make "en-rare" spell file.
@@ -121,8 +128,8 @@
 	http://spellchecker.mozdev.org/source.html
 	http://whiteboard.openoffice.org/source/browse/whiteboard/lingucomponent/source/spellcheck/myspell/
       author: Kevin Hendricks <kevin.hendricks@sympatico.ca>
-    - Update option window for 'verbosefile', 'spell', 'spellfile' and
-      'spelllang'.
+    - Update option window for 'verbosefile', 'spell', 'spellfile',
+      'spellsuggest' and 'spelllang'.
     - Distribution: Need wordlists for many languages; "language pack"
       Put them on the ftp site, ready to download.  Include README for
       copyrights.
diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt
index fa89204..40002dd 100644
--- a/runtime/doc/version7.txt
+++ b/runtime/doc/version7.txt
@@ -1,4 +1,4 @@
-*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jun 17
+*version7.txt*  For Vim version 7.0aa.  Last change: 2005 Jun 21
 
 
 		  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1137,5 +1137,8 @@
 setbufvar() and setwinvar() did not give error messages.
 
 It was possible to set a variable with an illegal name, e.g. with setbufvar().
+It was possible to define a function with illegal name, e.t. ":func F{-1}()"
+
+CTRL-W F and "gf" didn't use the same method to get the file name.
 
  vim:tw=78:ts=8:ft=help:norl:
diff --git a/runtime/spell/en.ascii.spl b/runtime/spell/en.ascii.spl
index a9ae844..8c6b0f2 100644
--- a/runtime/spell/en.ascii.spl
+++ b/runtime/spell/en.ascii.spl
Binary files differ
diff --git a/runtime/spell/en.latin1.spl b/runtime/spell/en.latin1.spl
index 6130166..ba4990c 100644
--- a/runtime/spell/en.latin1.spl
+++ b/runtime/spell/en.latin1.spl
Binary files differ
diff --git a/runtime/spell/en.utf-8.spl b/runtime/spell/en.utf-8.spl
index b4fecef..b8353c9 100644
--- a/runtime/spell/en.utf-8.spl
+++ b/runtime/spell/en.utf-8.spl
Binary files differ
diff --git a/runtime/syntax/c.vim b/runtime/syntax/c.vim
index eef3382..f826262 100644
--- a/runtime/syntax/c.vim
+++ b/runtime/syntax/c.vim
@@ -1,13 +1,10 @@
 " Vim syntax file
 " Language:	C
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2005 Jan 26
+" Last Change:	2005 Jun 20
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -298,63 +295,51 @@
 exec "syn sync ccomment cComment minlines=" . b:c_minlines
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_c_syn_inits")
-  if version < 508
-    let did_c_syn_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  HiLink cFormat		cSpecial
-  HiLink cCppString		cString
-  HiLink cCommentL		cComment
-  HiLink cCommentStart		cComment
-  HiLink cLabel			Label
-  HiLink cUserLabel		Label
-  HiLink cConditional		Conditional
-  HiLink cRepeat		Repeat
-  HiLink cCharacter		Character
-  HiLink cSpecialCharacter	cSpecial
-  HiLink cNumber		Number
-  HiLink cOctal			Number
-  HiLink cOctalZero		PreProc	 " link this to Error if you want
-  HiLink cFloat			Float
-  HiLink cOctalError		cError
-  HiLink cParenError		cError
-  HiLink cErrInParen		cError
-  HiLink cErrInBracket		cError
-  HiLink cCommentError		cError
-  HiLink cCommentStartError	cError
-  HiLink cSpaceError		cError
-  HiLink cSpecialError		cError
-  HiLink cOperator		Operator
-  HiLink cStructure		Structure
-  HiLink cStorageClass		StorageClass
-  HiLink cInclude		Include
-  HiLink cPreProc		PreProc
-  HiLink cDefine		Macro
-  HiLink cIncluded		cString
-  HiLink cError			Error
-  HiLink cStatement		Statement
-  HiLink cPreCondit		PreCondit
-  HiLink cType			Type
-  HiLink cConstant		Constant
-  HiLink cCommentString		cString
-  HiLink cComment2String	cString
-  HiLink cCommentSkip		cComment
-  HiLink cString		String
-  HiLink cComment		Comment
-  HiLink cSpecial		SpecialChar
-  HiLink cTodo			Todo
-  HiLink cCppSkip		cCppOut
-  HiLink cCppOut2		cCppOut
-  HiLink cCppOut		Comment
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link cFormat		cSpecial
+hi def link cCppString		cString
+hi def link cCommentL		cComment
+hi def link cCommentStart	cComment
+hi def link cLabel		Label
+hi def link cUserLabel		Label
+hi def link cConditional	Conditional
+hi def link cRepeat		Repeat
+hi def link cCharacter		Character
+hi def link cSpecialCharacter	cSpecial
+hi def link cNumber		Number
+hi def link cOctal		Number
+hi def link cOctalZero		PreProc	 " link this to Error if you want
+hi def link cFloat		Float
+hi def link cOctalError		cError
+hi def link cParenError		cError
+hi def link cErrInParen		cError
+hi def link cErrInBracket	cError
+hi def link cCommentError	cError
+hi def link cCommentStartError	cError
+hi def link cSpaceError		cError
+hi def link cSpecialError	cError
+hi def link cOperator		Operator
+hi def link cStructure		Structure
+hi def link cStorageClass	StorageClass
+hi def link cInclude		Include
+hi def link cPreProc		PreProc
+hi def link cDefine		Macro
+hi def link cIncluded		cString
+hi def link cError		Error
+hi def link cStatement		Statement
+hi def link cPreCondit		PreCondit
+hi def link cType		Type
+hi def link cConstant		Constant
+hi def link cCommentString	cString
+hi def link cComment2String	cString
+hi def link cCommentSkip	cComment
+hi def link cString		String
+hi def link cComment		Comment
+hi def link cSpecial		SpecialChar
+hi def link cTodo		Todo
+hi def link cCppSkip		cCppOut
+hi def link cCppOut2		cCppOut
+hi def link cCppOut		Comment
 
 let b:current_syntax = "c"
 
diff --git a/runtime/syntax/conf.vim b/runtime/syntax/conf.vim
index d08de4f..9b8a636 100644
--- a/runtime/syntax/conf.vim
+++ b/runtime/syntax/conf.vim
@@ -1,13 +1,10 @@
 " Vim syntax file
 " Language:	generic configure file
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2001 Apr 25
+" Last Change:	2005 Jun 20
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -19,22 +16,10 @@
 syn region	confString	start=+'+ skip=+\\\\\|\\'+ end=+'+ oneline
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_conf_syntax_inits")
-  if version < 508
-    let did_conf_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  HiLink confComment	Comment
-  HiLink confTodo	Todo
-  HiLink confString	String
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link confComment	Comment
+hi def link confTodo	Todo
+hi def link confString	String
 
 let b:current_syntax = "conf"
 
diff --git a/runtime/syntax/ctrlh.vim b/runtime/syntax/ctrlh.vim
index 715c2c0..b4bf347 100644
--- a/runtime/syntax/ctrlh.vim
+++ b/runtime/syntax/ctrlh.vim
@@ -1,7 +1,7 @@
 " Vim syntax file
 " Language:	CTRL-H (e.g., ASCII manpages)
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2001 Apr 25
+" Last Change:	2005 Jun 20
 
 " Existing syntax is kept, this file can be used as an addition
 
@@ -15,19 +15,9 @@
 syntax match CtrlHHide /.\b/  contained
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_ctrlh_syntax_inits")
-  if version < 508
-    let did_ctrlh_syntax_inits = 1
-    hi link CtrlHHide Ignore
-    hi CtrlHUnderline term=underline cterm=underline gui=underline
-    hi CtrlHBold term=bold cterm=bold gui=bold
-  else
-    hi def link CtrlHHide Ignore
-    hi def CtrlHUnderline term=underline cterm=underline gui=underline
-    hi def CtrlHBold term=bold cterm=bold gui=bold
-  endif
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link CtrlHHide Ignore
+hi def CtrlHUnderline term=underline cterm=underline gui=underline
+hi def CtrlHBold term=bold cterm=bold gui=bold
 
 " vim: ts=8
diff --git a/runtime/syntax/diff.vim b/runtime/syntax/diff.vim
index 2461abe..8ec6880 100644
--- a/runtime/syntax/diff.vim
+++ b/runtime/syntax/diff.vim
@@ -1,13 +1,10 @@
 " Vim syntax file
 " Language:	Diff (context or unified)
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2003 Apr 02
+" Last Change:	2005 Jun 20
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -43,35 +40,23 @@
 syn match diffComment	"^#.*"
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_diff_syntax_inits")
-  if version < 508
-    let did_diff_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  HiLink diffOldFile	diffFile
-  HiLink diffNewFile	diffFile
-  HiLink diffFile	Type
-  HiLink diffOnly	Constant
-  HiLink diffIdentical	Constant
-  HiLink diffDiffer	Constant
-  HiLink diffBDiffer	Constant
-  HiLink diffIsA	Constant
-  HiLink diffNoEOL	Constant
-  HiLink diffCommon	Constant
-  HiLink diffRemoved	Special
-  HiLink diffChanged	PreProc
-  HiLink diffAdded	Identifier
-  HiLink diffLine	Statement
-  HiLink diffSubname	PreProc
-  HiLink diffComment	Comment
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link diffOldFile		diffFile
+hi def link diffNewFile		diffFile
+hi def link diffFile		Type
+hi def link diffOnly		Constant
+hi def link diffIdentical	Constant
+hi def link diffDiffer		Constant
+hi def link diffBDiffer		Constant
+hi def link diffIsA		Constant
+hi def link diffNoEOL		Constant
+hi def link diffCommon		Constant
+hi def link diffRemoved		Special
+hi def link diffChanged		PreProc
+hi def link diffAdded		Identifier
+hi def link diffLine		Statement
+hi def link diffSubname		PreProc
+hi def link diffComment		Comment
 
 let b:current_syntax = "diff"
 
diff --git a/runtime/syntax/help.vim b/runtime/syntax/help.vim
index d363d88..7d50f55 100644
--- a/runtime/syntax/help.vim
+++ b/runtime/syntax/help.vim
@@ -1,13 +1,10 @@
 " Vim syntax file
 " Language:	Vim help file
 " Maintainer:	Bram Moolenaar (Bram@vim.org)
-" Last Change:	2005 Mar 31
+" Last Change:	2005 Jun 20
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -120,67 +117,55 @@
 
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_help_syntax_inits")
-  if version < 508
-    let did_help_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
+" Only used when an item doesn't have highlighting yet
+hi def link helpExampleStart	helpIgnore
+hi def link helpIgnore		Ignore
+hi def link helpHyperTextJump	Subtitle
+hi def link helpHyperTextEntry	String
+hi def link helpHeadline	Statement
+hi def link helpHeader		PreProc
+hi def link helpSectionDelim	PreProc
+hi def link helpVim		Identifier
+hi def link helpExample		Comment
+hi def link helpOption		Type
+hi def link helpNotVi		Special
+hi def link helpSpecial		Special
+hi def link helpNote		Todo
+hi def link Subtitle		Identifier
 
-  HiLink helpExampleStart	helpIgnore
-  HiLink helpIgnore		Ignore
-  HiLink helpHyperTextJump	Subtitle
-  HiLink helpHyperTextEntry	String
-  HiLink helpHeadline		Statement
-  HiLink helpHeader		PreProc
-  HiLink helpSectionDelim	PreProc
-  HiLink helpVim		Identifier
-  HiLink helpExample		Comment
-  HiLink helpOption		Type
-  HiLink helpNotVi		Special
-  HiLink helpSpecial		Special
-  HiLink helpNote		Todo
-  HiLink Subtitle		Identifier
-
-  HiLink helpComment		Comment
-  HiLink helpConstant		Constant
-  HiLink helpString		String
-  HiLink helpCharacter		Character
-  HiLink helpNumber		Number
-  HiLink helpBoolean		Boolean
-  HiLink helpFloat		Float
-  HiLink helpIdentifier		Identifier
-  HiLink helpFunction		Function
-  HiLink helpStatement		Statement
-  HiLink helpConditional	Conditional
-  HiLink helpRepeat		Repeat
-  HiLink helpLabel		Label
-  HiLink helpOperator		Operator
-  HiLink helpKeyword		Keyword
-  HiLink helpException		Exception
-  HiLink helpPreProc		PreProc
-  HiLink helpInclude		Include
-  HiLink helpDefine		Define
-  HiLink helpMacro		Macro
-  HiLink helpPreCondit		PreCondit
-  HiLink helpType		Type
-  HiLink helpStorageClass	StorageClass
-  HiLink helpStructure		Structure
-  HiLink helpTypedef		Typedef
-  HiLink helpSpecialChar	SpecialChar
-  HiLink helpTag		Tag
-  HiLink helpDelimiter		Delimiter
-  HiLink helpSpecialComment	SpecialComment
-  HiLink helpDebug		Debug
-  HiLink helpUnderlined		Underlined
-  HiLink helpError		Error
-  HiLink helpTodo		Todo
-
-  delcommand HiLink
-endif
+hi def link helpComment		Comment
+hi def link helpConstant	Constant
+hi def link helpString		String
+hi def link helpCharacter	Character
+hi def link helpNumber		Number
+hi def link helpBoolean		Boolean
+hi def link helpFloat		Float
+hi def link helpIdentifier	Identifier
+hi def link helpFunction	Function
+hi def link helpStatement	Statement
+hi def link helpConditional	Conditional
+hi def link helpRepeat		Repeat
+hi def link helpLabel		Label
+hi def link helpOperator	Operator
+hi def link helpKeyword		Keyword
+hi def link helpException	Exception
+hi def link helpPreProc		PreProc
+hi def link helpInclude		Include
+hi def link helpDefine		Define
+hi def link helpMacro		Macro
+hi def link helpPreCondit	PreCondit
+hi def link helpType		Type
+hi def link helpStorageClass	StorageClass
+hi def link helpStructure	Structure
+hi def link helpTypedef		Typedef
+hi def link helpSpecialChar	SpecialChar
+hi def link helpTag		Tag
+hi def link helpDelimiter	Delimiter
+hi def link helpSpecialComment	SpecialComment
+hi def link helpDebug		Debug
+hi def link helpUnderlined	Underlined
+hi def link helpError		Error
+hi def link helpTodo		Todo
 
 let b:current_syntax = "help"
 
diff --git a/runtime/syntax/model.vim b/runtime/syntax/model.vim
index 91b6781..5f3b7f8 100644
--- a/runtime/syntax/model.vim
+++ b/runtime/syntax/model.vim
@@ -1,16 +1,13 @@
 " Vim syntax file
 " Language:	Model
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2001 Apr 25
+" Last Change:	2005 Jun 20
 
 " very basic things only (based on the vgrindefs file).
 " If you use this language, please improve it, and send me the patches!
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -36,23 +33,11 @@
 syn match modelString "'."
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_model_syntax_inits")
-  if version < 508
-    let did_model_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  HiLink modelKeyword	Statement
-  HiLink modelBlock	PreProc
-  HiLink modelComment	Comment
-  HiLink modelString	String
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link modelKeyword	Statement
+hi def link modelBlock		PreProc
+hi def link modelComment	Comment
+hi def link modelString		String
 
 let b:current_syntax = "model"
 
diff --git a/runtime/syntax/vgrindefs.vim b/runtime/syntax/vgrindefs.vim
index a4b81b7..3de31b1 100644
--- a/runtime/syntax/vgrindefs.vim
+++ b/runtime/syntax/vgrindefs.vim
@@ -1,15 +1,12 @@
 " Vim syntax file
 " Language:	Vgrindefs
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2001 Apr 25
+" Last Change:	2005 Jun 20
 
 " The Vgrindefs file is used to specify a language for vgrind
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -39,22 +36,9 @@
 syn match vgrindefsField "\\$"
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_vgrindefs_syntax_inits")
-  if version < 508
-    let did_vgrindefs_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  " The default methods for highlighting.  Can be overridden later
-  HiLink vgrindefsField		Statement
-  HiLink vgrindefsComment	Comment
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link vgrindefsField	Statement
+hi def link vgrindefsComment	Comment
 
 let b:current_syntax = "vgrindefs"
 
diff --git a/runtime/syntax/viminfo.vim b/runtime/syntax/viminfo.vim
index 46d5b89..d174edf 100644
--- a/runtime/syntax/viminfo.vim
+++ b/runtime/syntax/viminfo.vim
@@ -1,13 +1,10 @@
 " Vim syntax file
 " Language:	Vim .viminfo file
 " Maintainer:	Bram Moolenaar <Bram@vim.org>
-" Last Change:	2001 Apr 25
+" Last Change:	2005 Jun 20
 
-" For version 5.x: Clear all syntax items
-" For version 6.x: Quit when a syntax file was already loaded
-if version < 600
-  syntax clear
-elseif exists("b:current_syntax")
+" Quit when a (custom) syntax file was already loaded
+if exists("b:current_syntax")
   finish
 endif
 
@@ -31,22 +28,10 @@
 syn match viminfoComment "^#.*"
 
 " Define the default highlighting.
-" For version 5.7 and earlier: only when not done already
-" For version 5.8 and later: only when an item doesn't have highlighting yet
-if version >= 508 || !exists("did_viminfo_syntax_inits")
-  if version < 508
-    let did_viminfo_syntax_inits = 1
-    command -nargs=+ HiLink hi link <args>
-  else
-    command -nargs=+ HiLink hi def link <args>
-  endif
-
-  HiLink viminfoComment		Comment
-  HiLink viminfoError		Error
-  HiLink viminfoStatement	Statement
-
-  delcommand HiLink
-endif
+" Only used when an item doesn't have highlighting yet
+hi def link viminfoComment	Comment
+hi def link viminfoError	Error
+hi def link viminfoStatement	Statement
 
 let b:current_syntax = "viminfo"
 
diff --git a/src/eval.c b/src/eval.c
index 6f31346..fb07e5e 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -540,6 +540,8 @@
 static void f_setwinvar __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_simplify __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_sort __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellbadword __ARGS((typval_T *argvars, typval_T *rettv));
+static void f_spellsuggest __ARGS((typval_T *argvars, typval_T *rettv));
 static void f_split __ARGS((typval_T *argvars, typval_T *rettv));
 #ifdef HAVE_STRFTIME
 static void f_strftime __ARGS((typval_T *argvars, typval_T *rettv));
@@ -6351,6 +6353,8 @@
     {"setwinvar",	3, 3, f_setwinvar},
     {"simplify",	1, 1, f_simplify},
     {"sort",		1, 2, f_sort},
+    {"spellbadword",	0, 0, f_spellbadword},
+    {"spellsuggest",	1, 2, f_spellsuggest},
     {"split",		1, 3, f_split},
 #ifdef HAVE_STRFTIME
     {"strftime",	1, 2, f_strftime},
@@ -13071,6 +13075,91 @@
     }
 }
 
+/*
+ * "spellbadword()" function
+ */
+/* ARGSUSED */
+    static void
+f_spellbadword(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    int		attr;
+    char_u	*ptr;
+    int		len;
+
+    rettv->vval.v_string = NULL;
+    rettv->v_type = VAR_STRING;
+
+#ifdef FEAT_SYN_HL
+    /* Find the start of the badly spelled word. */
+    if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL)
+	return;
+
+    /* Get the length of the word and copy it. */
+    ptr = ml_get_cursor();
+    len = spell_check(curwin, ptr, &attr);
+    rettv->vval.v_string = vim_strnsave(ptr, len);
+#endif
+}
+
+/*
+ * "spellsuggest()" function
+ */
+    static void
+f_spellsuggest(argvars, rettv)
+    typval_T	*argvars;
+    typval_T	*rettv;
+{
+    char_u	*str;
+    int		maxcount;
+    garray_T	ga;
+    list_T	*l;
+    listitem_T	*li;
+    int		i;
+
+    l = list_alloc();
+    if (l == NULL)
+	return;
+    rettv->v_type = VAR_LIST;
+    rettv->vval.v_list = l;
+    ++l->lv_refcount;
+
+#ifdef FEAT_SYN_HL
+    if (curwin->w_p_spell && *curbuf->b_p_spl != NUL)
+    {
+	str = get_tv_string(&argvars[0]);
+	if (argvars[1].v_type != VAR_UNKNOWN)
+	{
+	    maxcount = get_tv_number(&argvars[1]);
+	    if (maxcount <= 0)
+		return;
+	}
+	else
+	    maxcount = 25;
+
+	spell_suggest_list(&ga, str, maxcount);
+
+	for (i = 0; i < ga.ga_len; ++i)
+	{
+	    str = ((char_u **)ga.ga_data)[i];
+
+	    li = listitem_alloc();
+	    if (li == NULL)
+		vim_free(str);
+	    else
+	    {
+		li->li_tv.v_type = VAR_STRING;
+		li->li_tv.v_lock = 0;
+		li->li_tv.vval.v_string = str;
+		list_append(l, li);
+	    }
+	}
+	ga_clear(&ga);
+    }
+#endif
+}
+
     static void
 f_split(argvars, rettv)
     typval_T	*argvars;
@@ -16002,7 +16091,7 @@
      *		    "name" == NULL, "fudi.fd_dict" set,
      *		    "fudi.fd_di" == NULL, "fudi.fd_newkey" == func
      * dict.func    existing dict entry with a Funcref
-     *		    "name" == fname, "fudi.fd_dict" set,
+     *		    "name" == func, "fudi.fd_dict" set,
      *		    "fudi.fd_di" set, "fudi.fd_newkey" == NULL
      * dict.func    existing dict entry that's not a Funcref
      *		    "name" == NULL, "fudi.fd_dict" set,
@@ -16096,6 +16185,27 @@
     ga_init2(&newargs, (int)sizeof(char_u *), 3);
     ga_init2(&newlines, (int)sizeof(char_u *), 3);
 
+    if (!eap->skip)
+    {
+	/* Check the name of the function. */
+	if (name != NULL)
+	    arg = name;
+	else
+	    arg = fudi.fd_newkey;
+	if (arg != NULL)
+	{
+	    if (*arg == K_SPECIAL)
+		j = 3;
+	    else
+		j = 0;
+	    while (arg[j] != NUL && (j == 0 ? eval_isnamec1(arg[j])
+						      : eval_isnamec(arg[j])))
+		++j;
+	    if (arg[j] != NUL)
+		emsg_funcname(_(e_invarg2), arg);
+	}
+    }
+
     /*
      * Isolate the arguments: "arg1, arg2, ...)"
      */
@@ -16187,6 +16297,9 @@
 		emsg_funcname(e_funcexts, name);
 	}
 
+	if (!eap->skip && did_emsg)
+	    goto erret;
+
 	msg_putchar('\n');	    /* don't overwrite the function name */
 	cmdline_row = msg_row;
     }
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 20c58f1..1c1ecaa 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -135,6 +135,9 @@
 #endif
 static char_u	*invalid_range __ARGS((exarg_T *eap));
 static void	correct_range __ARGS((exarg_T *eap));
+#ifdef FEAT_QUICKFIX
+static char_u	*replace_makeprg __ARGS((exarg_T *eap, char_u *p, char_u **cmdlinep));
+#endif
 static char_u	*repl_cmdline __ARGS((exarg_T *eap, char_u *src, int srclen, char_u *repl, char_u **cmdlinep));
 static void	ex_highlight __ARGS((exarg_T *eap));
 static void	ex_colorscheme __ARGS((exarg_T *eap));
@@ -2187,71 +2190,10 @@
     /*
      * For the ":make" and ":grep" commands we insert the 'makeprg'/'grepprg'
      * option here, so things like % get expanded.
-     * Don't do it when ":vimgrep" is used for ":grep".
      */
-    if ((ea.cmdidx == CMD_make
-			 || ea.cmdidx == CMD_grep || ea.cmdidx == CMD_grepadd)
-	    && !grep_internal(ea.cmdidx))
-    {
-	char_u		*new_cmdline;
-	char_u		*program;
-	char_u		*pos;
-	char_u		*ptr;
-	int		len;
-	int		i;
-
-	if (ea.cmdidx == CMD_grep || ea.cmdidx == CMD_grepadd)
-	{
-	    if (*curbuf->b_p_gp == NUL)
-		program = p_gp;
-	    else
-		program = curbuf->b_p_gp;
-	}
-	else
-	{
-	    if (*curbuf->b_p_mp == NUL)
-		program = p_mp;
-	    else
-		program = curbuf->b_p_mp;
-	}
-
-	p = skipwhite(p);
-
-	if ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
-	{				/* replace $* by given arguments */
-	    i = 1;
-	    while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL)
-		++i;
-	    len = (int)STRLEN(p);
-	    new_cmdline = alloc((int)(STRLEN(program) + i * (len - 2) + 1));
-	    if (new_cmdline == NULL)
-		goto doend;		    /* out of memory */
-	    ptr = new_cmdline;
-	    while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
-	    {
-		i = (int)(pos - program);
-		STRNCPY(ptr, program, i);
-		STRCPY(ptr += i, p);
-		ptr += len;
-		program = pos + 2;
-	    }
-	    STRCPY(ptr, program);
-	}
-	else
-	{
-	    new_cmdline = alloc((int)(STRLEN(program) + STRLEN(p) + 2));
-	    if (new_cmdline == NULL)
-		goto doend;		    /* out of memory */
-	    STRCPY(new_cmdline, program);
-	    STRCAT(new_cmdline, " ");
-	    STRCAT(new_cmdline, p);
-	}
-	msg_make(p);
-	/* 'ea.cmd' is not set here, because it is not used at CMD_make */
-	vim_free(*cmdlinep);
-	*cmdlinep = new_cmdline;
-	p = new_cmdline;
-    }
+    p = replace_makeprg(&ea, p, cmdlinep);
+    if (p == NULL)
+	goto doend;
 #endif
 
     /*
@@ -4031,6 +3973,87 @@
     }
     return p;
 }
+
+/*
+ * For the ":make" and ":grep" commands insert the 'makeprg'/'grepprg' option
+ * in the command line, so that things like % get expanded.
+ */
+    static char_u *
+replace_makeprg(eap, p, cmdlinep)
+    exarg_T	*eap;
+    char_u	*p;
+    char_u	**cmdlinep;
+{
+    char_u	*new_cmdline;
+    char_u	*program;
+    char_u	*pos;
+    char_u	*ptr;
+    int		len;
+    int		i;
+
+    /*
+     * Don't do it when ":vimgrep" is used for ":grep".
+     */
+    if ((eap->cmdidx == CMD_make
+		     || eap->cmdidx == CMD_grep || eap->cmdidx == CMD_grepadd)
+	    && !grep_internal(eap->cmdidx))
+    {
+	if (eap->cmdidx == CMD_grep || eap->cmdidx == CMD_grepadd)
+	{
+	    if (*curbuf->b_p_gp == NUL)
+		program = p_gp;
+	    else
+		program = curbuf->b_p_gp;
+	}
+	else
+	{
+	    if (*curbuf->b_p_mp == NUL)
+		program = p_mp;
+	    else
+		program = curbuf->b_p_mp;
+	}
+
+	p = skipwhite(p);
+
+	if ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
+	{
+	    /* replace $* by given arguments */
+	    i = 1;
+	    while ((pos = (char_u *)strstr((char *)pos + 2, "$*")) != NULL)
+		++i;
+	    len = (int)STRLEN(p);
+	    new_cmdline = alloc((int)(STRLEN(program) + i * (len - 2) + 1));
+	    if (new_cmdline == NULL)
+		return NULL;			/* out of memory */
+	    ptr = new_cmdline;
+	    while ((pos = (char_u *)strstr((char *)program, "$*")) != NULL)
+	    {
+		i = (int)(pos - program);
+		STRNCPY(ptr, program, i);
+		STRCPY(ptr += i, p);
+		ptr += len;
+		program = pos + 2;
+	    }
+	    STRCPY(ptr, program);
+	}
+	else
+	{
+	    new_cmdline = alloc((int)(STRLEN(program) + STRLEN(p) + 2));
+	    if (new_cmdline == NULL)
+		return NULL;			/* out of memory */
+	    STRCPY(new_cmdline, program);
+	    STRCAT(new_cmdline, " ");
+	    STRCAT(new_cmdline, p);
+	}
+	msg_make(p);
+
+	/* 'eap->cmd' is not set here, because it is not used at CMD_make */
+	vim_free(*cmdlinep);
+	*cmdlinep = new_cmdline;
+	p = new_cmdline;
+    }
+    return p;
+}
 #endif
 
 /*
diff --git a/src/fileio.c b/src/fileio.c
index e239b5c..9ae69cf 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -3183,7 +3183,7 @@
 	    struct stat	st_new;
 	    char_u	*dirp;
 	    char_u	*rootname;
-#ifndef SHORT_FNAME
+#if defined(UNIX) && !defined(SHORT_FNAME)
 	    int		did_set_shortname;
 #endif
 
@@ -3226,7 +3226,7 @@
 		    goto nobackup;
 		}
 
-#ifndef SHORT_FNAME
+#if defined(UNIX) && !defined(SHORT_FNAME)
 		did_set_shortname = FALSE;
 #endif
 
diff --git a/src/glbl_ime.h b/src/glbl_ime.h
index 8508836..2bdffc6 100644
--- a/src/glbl_ime.h
+++ b/src/glbl_ime.h
@@ -14,15 +14,15 @@
 extern "C" {
 #endif /* __cplusplus */
     void global_ime_init(ATOM, HWND);
-    void global_ime_end();
+    void global_ime_end(void);
     LRESULT WINAPI global_ime_DefWindowProc(HWND, UINT, WPARAM, LPARAM);
     BOOL WINAPI global_ime_TranslateMessage(CONST MSG *);
     void WINAPI global_ime_set_position(POINT*);
     void WINAPI global_ime_set_font(LOGFONT*);
-    void WINAPI global_ime_status_evacuate();
-    void WINAPI global_ime_status_restore();
+    void WINAPI global_ime_status_evacuate(void);
+    void WINAPI global_ime_status_restore(void);
     void WINAPI global_ime_set_status(int status);
-    int WINAPI global_ime_get_status();
+    int WINAPI global_ime_get_status(void);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
diff --git a/src/globals.h b/src/globals.h
index c073fcb..87b99e3 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -85,8 +85,6 @@
 #endif
 EXTERN int	exec_from_reg INIT(= FALSE);	/* executing register */
 
-EXTERN int	global_changedtick INIT(= 0);	/* incremented for each
-						   change, also for undo */
 EXTERN int	screen_cleared INIT(= FALSE);	/* screen has been cleared */
 
 /*
@@ -961,10 +959,6 @@
  */
 EXTERN char_u	*empty_option INIT(= (char_u *)"");
 
-#ifdef DEBUG
-EXTERN FILE *debugfp INIT(= NULL);
-#endif
-
 EXTERN int  redir_off INIT(= FALSE);	/* no redirection for a moment */
 EXTERN FILE *redir_fd INIT(= NULL);	/* message redirection file */
 #ifdef FEAT_EVAL
diff --git a/src/gui_gtk.c b/src/gui_gtk.c
index 641f784..cd7d6bb 100644
--- a/src/gui_gtk.c
+++ b/src/gui_gtk.c
@@ -172,6 +172,9 @@
 static void entry_activate_cb(GtkWidget *widget, gpointer data);
 static void entry_changed_cb(GtkWidget *entry, GtkWidget *dialog);
 static void find_replace_cb(GtkWidget *widget, gpointer data);
+#ifndef HAVE_GTK2
+static void gui_gtk_position_in_parent(GtkWidget *parent, GtkWidget *child, gui_win_pos_T where);
+#endif
 
 #if defined(FEAT_TOOLBAR) && defined(HAVE_GTK2)
 /*
@@ -3093,7 +3096,7 @@
  *
  *  brent -- dbv
  */
-    void
+    static void
 gui_gtk_position_in_parent(
 	GtkWidget	*parent,
 	GtkWidget	*child,
diff --git a/src/gui_w32.c b/src/gui_w32.c
index 3e31e77..c4d8e48 100644
--- a/src/gui_w32.c
+++ b/src/gui_w32.c
@@ -258,18 +258,18 @@
 typedef HANDLE HIMC;
 # endif
 
-HINSTANCE hLibImm = NULL;
-LONG (WINAPI *pImmGetCompositionStringA)(HIMC, DWORD, LPVOID, DWORD);
-LONG (WINAPI *pImmGetCompositionStringW)(HIMC, DWORD, LPVOID, DWORD);
-HIMC (WINAPI *pImmGetContext)(HWND);
-HIMC (WINAPI *pImmAssociateContext)(HWND, HIMC);
-BOOL (WINAPI *pImmReleaseContext)(HWND, HIMC);
-BOOL (WINAPI *pImmGetOpenStatus)(HIMC);
-BOOL (WINAPI *pImmSetOpenStatus)(HIMC, BOOL);
-BOOL (WINAPI *pImmGetCompositionFont)(HIMC, LPLOGFONTA);
-BOOL (WINAPI *pImmSetCompositionFont)(HIMC, LPLOGFONTA);
-BOOL (WINAPI *pImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
-BOOL (WINAPI *pImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
+static HINSTANCE hLibImm = NULL;
+static LONG (WINAPI *pImmGetCompositionStringA)(HIMC, DWORD, LPVOID, DWORD);
+static LONG (WINAPI *pImmGetCompositionStringW)(HIMC, DWORD, LPVOID, DWORD);
+static HIMC (WINAPI *pImmGetContext)(HWND);
+static HIMC (WINAPI *pImmAssociateContext)(HWND, HIMC);
+static BOOL (WINAPI *pImmReleaseContext)(HWND, HIMC);
+static BOOL (WINAPI *pImmGetOpenStatus)(HIMC);
+static BOOL (WINAPI *pImmSetOpenStatus)(HIMC, BOOL);
+static BOOL (WINAPI *pImmGetCompositionFont)(HIMC, LPLOGFONTA);
+static BOOL (WINAPI *pImmSetCompositionFont)(HIMC, LPLOGFONTA);
+static BOOL (WINAPI *pImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
+static BOOL (WINAPI *pImmGetConversionStatus)(HIMC, LPDWORD, LPDWORD);
 static void dyn_imm_load(void);
 #else
 # define pImmGetCompositionStringA ImmGetCompositionStringA
@@ -1443,6 +1443,7 @@
 /*
  * handle WM_IME_NOTIFY message
  */
+/*ARGSUSED*/
     static LRESULT
 _OnImeNotify(HWND hWnd, DWORD dwCommand, DWORD dwData)
 {
@@ -1492,6 +1493,7 @@
     return lResult;
 }
 
+/*ARGSUSED*/
     static LRESULT
 _OnImeComposition(HWND hwnd, WPARAM dbcs, LPARAM param)
 {
@@ -4147,6 +4149,7 @@
     // TRACE0("gui_mch_post_balloon }}}");
 }
 
+/*ARGSUSED*/
     BalloonEval *
 gui_mch_create_beval_area(target, mesg, mesgCB, clientData)
     void	*target;	/* ignored, always use s_textArea */
diff --git a/src/if_mzsch.c b/src/if_mzsch.c
index c67c46d..dde31eb 100644
--- a/src/if_mzsch.c
+++ b/src/if_mzsch.c
@@ -225,7 +225,7 @@
 static Scheme_Object *(*dll_scheme_eval)(Scheme_Object *obj, Scheme_Env *env);
 static Scheme_Object *(*dll_scheme_eval_string)(const char *str,
 	Scheme_Env *env);
-static Scheme_Object *(*dll_scheme_eval_string_all)(const char *str, 
+static Scheme_Object *(*dll_scheme_eval_string_all)(const char *str,
 	Scheme_Env *env, int all);
 static void (*dll_scheme_finish_primitive_module)(Scheme_Env *env);
 # if MZSCHEME_VERSION_MAJOR < 299
@@ -253,7 +253,7 @@
 static Scheme_Object *(*dll_scheme_make_integer_value)(long i);
 static Scheme_Object *(*dll_scheme_make_namespace)(int argc,
 	Scheme_Object *argv[]);
-static Scheme_Object *(*dll_scheme_make_pair)(Scheme_Object *car, 
+static Scheme_Object *(*dll_scheme_make_pair)(Scheme_Object *car,
 	Scheme_Object *cdr);
 static Scheme_Object *(*dll_scheme_make_prim_w_arity)(Scheme_Prim *prim,
 	const char *name, mzshort mina, mzshort maxa);
@@ -294,7 +294,7 @@
 static void (*dll_scheme_wrong_type)(const char *name, const char *expected,
 	int which, int argc, Scheme_Object **argv);
 # if MZSCHEME_VERSION_MAJOR >= 299
-static void (*dll_scheme_set_param)(Scheme_Config *c, int pos, 
+static void (*dll_scheme_set_param)(Scheme_Config *c, int pos,
 	Scheme_Object *o);
 static Scheme_Config *(*dll_scheme_current_config)(void);
 static Scheme_Object *(*dll_scheme_char_string_to_byte_string)
@@ -411,7 +411,7 @@
     {"scheme_current_thread", (void **)&dll_scheme_current_thread_ptr},
     {"scheme_console_printf", (void **)&dll_scheme_console_printf_ptr},
     {"scheme_console_output", (void **)&dll_scheme_console_output_ptr},
-    {"scheme_notify_multithread", 
+    {"scheme_notify_multithread",
 	(void **)&dll_scheme_notify_multithread_ptr},
     {"scheme_add_global", (void **)&dll_scheme_add_global},
     {"scheme_add_global_symbol", (void **)&dll_scheme_add_global_symbol},
@@ -424,7 +424,7 @@
     {"scheme_check_threads", (void **)&dll_scheme_check_threads},
     {"scheme_close_input_port", (void **)&dll_scheme_close_input_port},
     {"scheme_count_lines", (void **)&dll_scheme_count_lines},
-    {"scheme_current_continuation_marks", 
+    {"scheme_current_continuation_marks",
 	(void **)&dll_scheme_current_continuation_marks},
     {"scheme_display", (void **)&dll_scheme_display},
     {"scheme_display_to_string", (void **)&dll_scheme_display_to_string},
@@ -434,7 +434,7 @@
     {"scheme_eval", (void **)&dll_scheme_eval},
     {"scheme_eval_string", (void **)&dll_scheme_eval_string},
     {"scheme_eval_string_all", (void **)&dll_scheme_eval_string_all},
-    {"scheme_finish_primitive_module", 
+    {"scheme_finish_primitive_module",
 	(void **)&dll_scheme_finish_primitive_module},
 # if MZSCHEME_VERSION_MAJOR < 299
     {"scheme_format", (void **)&dll_scheme_format},
@@ -444,15 +444,15 @@
 #endif
     {"scheme_gc_ptr_ok", (void **)&dll_scheme_gc_ptr_ok},
 # if MZSCHEME_VERSION_MAJOR < 299
-    {"scheme_get_sized_string_output", 
+    {"scheme_get_sized_string_output",
 	(void **)&dll_scheme_get_sized_string_output},
 # else
-    {"scheme_get_sized_byte_string_output", 
+    {"scheme_get_sized_byte_string_output",
 	(void **)&dll_scheme_get_sized_byte_string_output},
 #endif
     {"scheme_intern_symbol", (void **)&dll_scheme_intern_symbol},
     {"scheme_lookup_global", (void **)&dll_scheme_lookup_global},
-    {"scheme_make_closed_prim_w_arity", 
+    {"scheme_make_closed_prim_w_arity",
 	(void **)&dll_scheme_make_closed_prim_w_arity},
     {"scheme_make_integer_value", (void **)&dll_scheme_make_integer_value},
     {"scheme_make_namespace", (void **)&dll_scheme_make_namespace},
@@ -460,14 +460,14 @@
     {"scheme_make_prim_w_arity", (void **)&dll_scheme_make_prim_w_arity},
 # if MZSCHEME_VERSION_MAJOR < 299
     {"scheme_make_string", (void **)&dll_scheme_make_string},
-    {"scheme_make_string_output_port", 
+    {"scheme_make_string_output_port",
 	(void **)&dll_scheme_make_string_output_port},
 # else
     {"scheme_make_byte_string", (void **)&dll_scheme_make_byte_string},
-    {"scheme_make_byte_string_output_port", 
+    {"scheme_make_byte_string_output_port",
 	(void **)&dll_scheme_make_byte_string_output_port},
 # endif
-    {"scheme_make_struct_instance", 
+    {"scheme_make_struct_instance",
 	(void **)&dll_scheme_make_struct_instance},
     {"scheme_make_struct_names", (void **)&dll_scheme_make_struct_names},
     {"scheme_make_struct_type", (void **)&dll_scheme_make_struct_type},
@@ -525,7 +525,7 @@
 
     for (thunk = mzsch_imports; thunk->name; thunk++)
     {
-	if ((*thunk->ptr = 
+	if ((*thunk->ptr =
 		    (void *)GetProcAddress(hMzSch, thunk->name)) == NULL)
 	{
 	    FreeLibrary(hMzSch);
@@ -539,7 +539,7 @@
     }
     for (thunk = mzgc_imports; thunk->name; thunk++)
     {
-	if ((*thunk->ptr = 
+	if ((*thunk->ptr =
 		    (void *)GetProcAddress(hMzGC, thunk->name)) == NULL)
 	{
 	    FreeLibrary(hMzSch);
@@ -2655,7 +2655,7 @@
     scheme_add_global("global-namespace", (Scheme_Object *)environment, mod);
     scheme_finish_primitive_module(mod);
 }
-    
+
 #ifdef HAVE_SANDBOX
 static Scheme_Object *M_write = NULL;
 static Scheme_Object *M_read = NULL;
@@ -2669,7 +2669,7 @@
 	raise_vim_exn(_("not allowed in the Vim sandbox"));
 }
 
-/* security guards to force Vim's sandbox restrictions on MzScheme level */ 
+/* security guards to force Vim's sandbox restrictions on MzScheme level */
     static Scheme_Object *
 sandbox_file_guard(int argc, Scheme_Object **argv)
 {
diff --git a/src/mbyte.c b/src/mbyte.c
index b73b095..ef091e3 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -3178,11 +3178,11 @@
 	return FALSE;
     }
 
-    *((FARPROC*)&iconv)		= GetProcAddress(hIconvDLL, "libiconv");
-    *((FARPROC*)&iconv_open)	= GetProcAddress(hIconvDLL, "libiconv_open");
-    *((FARPROC*)&iconv_close)	= GetProcAddress(hIconvDLL, "libiconv_close");
-    *((FARPROC*)&iconvctl)	= GetProcAddress(hIconvDLL, "libiconvctl");
-    *((FARPROC*)&iconv_errno)	= GetProcAddress(hMsvcrtDLL, "_errno");
+    iconv	= (void *)GetProcAddress(hIconvDLL, "libiconv");
+    iconv_open	= (void *)GetProcAddress(hIconvDLL, "libiconv_open");
+    iconv_close	= (void *)GetProcAddress(hIconvDLL, "libiconv_close");
+    iconvctl	= (void *)GetProcAddress(hIconvDLL, "libiconvctl");
+    iconv_errno	= (void *)GetProcAddress(hMsvcrtDLL, "_errno");
     if (iconv == NULL || iconv_open == NULL || iconv_close == NULL
 	    || iconvctl == NULL || iconv_errno == NULL)
     {
diff --git a/src/misc1.c b/src/misc1.c
index 7209a1a..30d7696 100644
--- a/src/misc1.c
+++ b/src/misc1.c
@@ -2461,7 +2461,6 @@
 #endif
     }
     ++curbuf->b_changedtick;
-    ++global_changedtick;
 }
 
 static void changedOneline __ARGS((buf_T *buf, linenr_T lnum));
@@ -2851,7 +2850,6 @@
 #endif
     }
     ++buf->b_changedtick;
-    ++global_changedtick;
 #ifdef FEAT_NETBEANS_INTG
     netbeans_unmodified(buf);
 #endif
@@ -3144,9 +3142,18 @@
 prompt_for_number()
 {
     int		i;
+    int		save_cmdline_row;
+    int		save_State;
 
     /* When using ":silent" assume that <CR> was entered. */
     MSG_PUTS(_("Choice number (<Enter> cancels): "));
+
+    /* Set the state such that text can be selected/copied/pasted. */
+    save_cmdline_row = cmdline_row;
+    cmdline_row = Rows - 1;
+    save_State = State;
+    State = CMDLINE;
+
     i = get_number(TRUE);
     if (KeyTyped)		/* don't call wait_return() now */
     {
@@ -3155,6 +3162,10 @@
 	need_wait_return = FALSE;
 	msg_didany = FALSE;
     }
+    else
+	cmdline_row = save_cmdline_row;
+    State = save_State;
+
     return i;
 }
 
diff --git a/src/netbeans.c b/src/netbeans.c
index f6fb52c..bebfa5e 100644
--- a/src/netbeans.c
+++ b/src/netbeans.c
@@ -188,7 +188,7 @@
 #endif /* FEAT_GUI_GTK */
 
 #if defined(FEAT_GUI_W32) || defined(PROTO)
-    void
+    static void
 netbeans_w32_connect(void)
 {
     netbeans_connect();
@@ -742,7 +742,7 @@
 	nbdebug(("messageFromNetbeans: Error in read() from socket\n"));
 	if (len < 0)
 	    PERROR(_("read from Netbeans socket"));
-	return; /* don't try to parse it */;
+	return; /* don't try to parse it */
     }
 
     /* Parse the messages, but avoid recursion. */
@@ -863,8 +863,8 @@
 typedef struct nbbuf_struct nbbuf_T;
 
 static nbbuf_T *buf_list = 0;
-int buf_list_size = 0;	/* size of buf_list */
-int buf_list_used = 0;	/* nr of entries in buf_list actually in use */
+static int buf_list_size = 0;	/* size of buf_list */
+static int buf_list_used = 0;	/* nr of entries in buf_list actually in use */
 
 static char **globalsignmap;
 static int globalsignmaplen;
diff --git a/src/normal.c b/src/normal.c
index fa5e355..ca26bb3 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -81,9 +81,6 @@
 static void	nv_hat __ARGS((cmdarg_T *cap));
 static void	nv_Zet __ARGS((cmdarg_T *cap));
 static void	nv_ident __ARGS((cmdarg_T *cap));
-#ifdef FEAT_VISUAL
-static int	get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
-#endif
 static void	nv_tagpop __ARGS((cmdarg_T *cap));
 static void	nv_scroll __ARGS((cmdarg_T *cap));
 static void	nv_right __ARGS((cmdarg_T *cap));
@@ -5167,12 +5164,12 @@
     vim_free(buf);
 }
 
-#ifdef FEAT_VISUAL
+#if defined(FEAT_VISUAL) || defined(PROTO)
 /*
  * Get visually selected text, within one line only.
  * Returns FAIL if more than one line selected.
  */
-    static int
+    int
 get_visual_text(cap, pp, lenp)
     cmdarg_T	*cap;
     char_u	**pp;	    /* return: start of selected text */
@@ -5182,7 +5179,8 @@
 	unadjust_for_sel();
     if (VIsual.lnum != curwin->w_cursor.lnum)
     {
-	clearopbeep(cap->oap);
+	if (cap != NULL)
+	    clearopbeep(cap->oap);
 	return FAIL;
     }
     if (VIsual_mode == 'V')
@@ -5592,24 +5590,7 @@
     }
 #endif
 
-# ifdef FEAT_VISUAL
-    /*
-     * In Visual mode, use the selected text as a file name.
-     * Don't allow selection across multiple lines.
-     */
-    if (VIsual_active)
-    {
-	int	len;
-
-	if (get_visual_text(cap, &ptr, &len) == FAIL)
-	    return;
-	ptr = find_file_name_in_path(ptr, len,
-	       FNAME_MESS|FNAME_EXP|FNAME_REL, cap->count1, curbuf->b_ffname);
-    }
-    else
-# endif
-	ptr = file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP|FNAME_REL,
-								 cap->count1);
+    ptr = grab_file_name(cap->count1);
 
     if (ptr != NULL)
     {
diff --git a/src/option.c b/src/option.c
index c0ea094..97c0aa5 100644
--- a/src/option.c
+++ b/src/option.c
@@ -2049,6 +2049,15 @@
 			    {(char_u *)0L, (char_u *)0L}
 #endif
 			    },
+    {"spellsuggest", "sps", P_STRING|P_VI_DEF,
+#ifdef FEAT_SYN_HL
+			    (char_u *)&p_sps, PV_NONE,
+			    {(char_u *)"best", (char_u *)0L}
+#else
+			    (char_u *)NULL, PV_NONE,
+			    {(char_u *)0L, (char_u *)0L}
+#endif
+    },
     {"splitbelow",  "sb",   P_BOOL|P_VI_DEF,
 #ifdef FEAT_WINDOWS
 			    (char_u *)&p_sb, PV_NONE,
@@ -4552,6 +4561,9 @@
 #if defined(FEAT_MOUSE) && (defined(UNIX) || defined(VMS))
     (void)opt_strings_flags(p_ttym, p_ttym_values, &ttym_flags, FALSE);
 #endif
+#ifdef FEAT_SYN_HL
+    (void)opt_strings_flags(p_sps, p_sps_values, &sps_flags, FALSE);
+#endif
 #if defined(FEAT_TOOLBAR) && !defined(FEAT_GUI_W32)
     (void)opt_strings_flags(p_toolbar, p_toolbar_values, &toolbar_flags, TRUE);
 #endif
@@ -5710,6 +5722,12 @@
 		}
 	}
     }
+    /* 'spellsuggest' */
+    else if (varp == &p_sps)
+    {
+	if (opt_strings_flags(p_sps, p_sps_values, &sps_flags, FALSE) != OK)
+	    errmsg = e_invarg;
+    }
 #endif
 
 #ifdef FEAT_AUTOCMD
diff --git a/src/option.h b/src/option.h
index d52f3c6..0be4ac3 100644
--- a/src/option.h
+++ b/src/option.h
@@ -706,6 +706,16 @@
 #ifdef FEAT_WINDOWS
 EXTERN int	p_sb;		/* 'splitbelow' */
 #endif
+#ifdef FEAT_SYN_HL
+EXTERN char_u	*p_sps;		/* 'spellsuggest' */
+EXTERN unsigned sps_flags;
+# ifdef IN_OPTION_C
+static char *(p_sps_values[]) = {"best", "fast", "double", NULL};
+# endif
+# define SPS_BEST		0x01
+# define SPS_FAST		0x02
+# define SPS_DOUBLE		0x04
+#endif
 #ifdef FEAT_VERTSPLIT
 EXTERN int	p_spr;		/* 'splitright' */
 #endif
diff --git a/src/os_win32.c b/src/os_win32.c
index 82a3ce0..3184e2e 100644
--- a/src/os_win32.c
+++ b/src/os_win32.c
@@ -1325,6 +1325,7 @@
  * If time == -1, wait forever for characters.
  * Returns the number of characters read into buf.
  */
+/*ARGSUSED*/
     int
 mch_inchar(
     char_u	*buf,
@@ -4190,6 +4191,7 @@
  * How much memory is available?
  * Return sum of available physical and page file memory.
  */
+/*ARGSUSED*/
     long_u
 mch_avail_mem(int special)
 {
@@ -4867,7 +4869,7 @@
 /*
  * The command line arguments in UCS2
  */
-static DWORD	nArgsW = 0;
+static int	nArgsW = 0;
 static LPWSTR	*ArglistW = NULL;
 static int	global_argc = 0;
 static char	**global_argv;
@@ -4994,7 +4996,7 @@
      * - the file name arguments must have been located.
      * - the length of the argument list wasn't changed by the user.
      */
-    if (global_argc != (int)nArgsW
+    if (global_argc != nArgsW
 	    || ArglistW == NULL
 	    || used_file_indexes == NULL
 	    || used_file_count == 0
diff --git a/src/proto/gui_gtk.pro b/src/proto/gui_gtk.pro
index afe38dc..818d12c 100644
--- a/src/proto/gui_gtk.pro
+++ b/src/proto/gui_gtk.pro
@@ -20,5 +20,4 @@
 void gui_mch_replace_dialog __ARGS((exarg_T *eap));
 void gui_gtk_synch_fonts __ARGS((void));
 void ex_helpfind __ARGS((exarg_T *eap));
-void gui_gtk_position_in_parent __ARGS((GtkWidget *parent, GtkWidget *child, gui_win_pos_T where));
 /* vim: set ft=c : */
diff --git a/src/proto/netbeans.pro b/src/proto/netbeans.pro
index f6b7d7d..75d0149 100644
--- a/src/proto/netbeans.pro
+++ b/src/proto/netbeans.pro
@@ -1,5 +1,4 @@
 /* netbeans.c */
-void netbeans_w32_connect __ARGS((void));
 void messageFromNetbeansW32 __ARGS((void));
 int isNetbeansBuffer __ARGS((buf_T *bufp));
 int isNetbeansModified __ARGS((buf_T *bufp));
diff --git a/src/proto/normal.pro b/src/proto/normal.pro
index f5e332b..74364e3 100644
--- a/src/proto/normal.pro
+++ b/src/proto/normal.pro
@@ -18,6 +18,7 @@
 void check_scrollbind __ARGS((linenr_T topline_diff, long leftcol_diff));
 void scroll_redraw __ARGS((int up, long count));
 void do_nv_ident __ARGS((int c1, int c2));
+int get_visual_text __ARGS((cmdarg_T *cap, char_u **pp, int *lenp));
 void start_selection __ARGS((void));
 void may_start_select __ARGS((int c));
 /* vim: set ft=c : */
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index c932b1f..15a68a6 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -9,4 +9,5 @@
 void spell_add_word __ARGS((char_u *word, int len, int bad));
 void init_spell_chartab __ARGS((void));
 void spell_suggest __ARGS((void));
+void spell_suggest_list __ARGS((garray_T *gap, char_u *word, int maxcount));
 /* vim: set ft=c : */
diff --git a/src/proto/window.pro b/src/proto/window.pro
index 243bd7b..f01eee0 100644
--- a/src/proto/window.pro
+++ b/src/proto/window.pro
@@ -31,6 +31,7 @@
 void win_comp_scroll __ARGS((win_T *wp));
 void command_height __ARGS((long old_p_ch));
 void last_status __ARGS((int morewin));
+char_u *grab_file_name __ARGS((long count));
 char_u *file_name_at_cursor __ARGS((int options, long count));
 char_u *file_name_in_line __ARGS((char_u *line, int col, int options, long count, char_u *rel_fname));
 char_u *find_file_name_in_path __ARGS((char_u *ptr, int len, int options, long count, char_u *rel_fname));
diff --git a/src/spell.c b/src/spell.c
index a12c0cc..eab725a 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -51,18 +51,28 @@
  */
 
 /*
- * Use this to let the score depend in how much a suggestion sounds like the
- * bad word.  It's quite slow and only occasionally makes the sorting better.
-#define SOUNDFOLD_SCORE
- */
-
-/*
  * 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 different and goes
  * down in the list.
-#define RESCORE(word_score, sound_score) ((2 * word_score + sound_score) / 3)
+ * Used when 'spellsuggest' is set to "best".
+ */
+#define RESCORE(word_score, sound_score) ((3 * word_score + sound_score) / 4)
+
+/*
+ * The double scoring mechanism is based on the principle that there are two
+ * kinds of spelling mistakes:
+ * 1. You know how to spell the word, but mistype something.  This results in
+ *    a small editing distance (character swapped/omitted/inserted) and
+ *    possibly a word that sounds completely different.
+ * 2. You don't know how to spell the word and type something that sounds
+ *    right.  The edit distance can be big but the word is similar after
+ *    sound-folding.
+ * Since scores for these two mistakes will be very different we use a list
+ * for each.
+ * The sound-folding is slow, only do double scoring when 'spellsuggest' is
+ * "double".
  */
 
 /*
@@ -231,7 +241,7 @@
 #define BY_SPECIAL  BY_INDEX	/* hightest special byte value */
 
 /* Info from "REP" and "SAL" entries in ".aff" file used in si_rep, sl_rep,
- * si_sal and sl_sal.
+ * and si_sal.  Not for sl_sal!
  * One replacement: from "ft_from" to "ft_to". */
 typedef struct fromto_S
 {
@@ -239,6 +249,18 @@
     char_u	*ft_to;
 } fromto_T;
 
+/* Info from "SAL" entries in ".aff" file used in sl_sal.
+ * The info is split for quick processing by spell_soundfold().
+ * Note that "sm_oneof" and "sm_rules" point into sm_lead. */
+typedef struct salitem_S
+{
+    char_u	*sm_lead;	/* leading letters */
+    int		sm_leadlen;	/* length of "sm_lead" */
+    char_u	*sm_oneoff;	/* letters from () or NULL */
+    char_u	*sm_rules;	/* rules like ^, $, priority */
+    char_u	*sm_to;		/* replacement. */
+} salitem_T;
+
 /*
  * Structure used to store words and other info for one language, loaded from
  * a .spl file.
@@ -277,7 +299,7 @@
     garray_T	sl_rep;		/* list of fromto_T entries from REP lines */
     short	sl_rep_first[256];  /* indexes where byte first appears, -1 if
 				       there is none */
-    garray_T	sl_sal;		/* list of fromto_T entries from SAL lines */
+    garray_T	sl_sal;		/* list of salitem_T entries from SAL lines */
     short	sl_sal_first[256];  /* indexes where byte first appears, -1 if
 				       there is none */
     int		sl_followup;	/* SAL followup */
@@ -330,16 +352,14 @@
 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 */
+    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 */
     char_u	su_badword[MAXWLEN]; /* bad word truncated at su_badlen */
     char_u	su_fbadword[MAXWLEN]; /* su_badword case-folded */
     hashtab_T	su_banned;	    /* table with banned words */
-#ifdef SOUNDFOLD_SCORE
-    slang_T	*su_slang;	    /* currently used slang_T */
-    char_u	su_salword[MAXWLEN]; /* soundfolded badword */
-#endif
 } suginfo_T;
 
 /* One word suggestion.  Used in "si_ga". */
@@ -348,32 +368,27 @@
     char_u	*st_word;	/* suggested word, allocated string */
     int		st_orglen;	/* length of replaced text */
     int		st_score;	/* lower is better */
-#ifdef RESCORE
+    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 */
-#endif
 } suggest_T;
 
-#define SUG(sup, i) (((suggest_T *)(sup)->su_ga.ga_data)[i])
-
-/* Number of suggestions displayed. */
-#define SUG_PROMPT_COUNT    ((int)Rows - 2)
+#define SUG(ga, i) (((suggest_T *)(ga).ga_data)[i])
 
 /* Number of suggestions kept when cleaning up.  When rescore_suggestions() is
  * called the score may change, thus we need to keep more than what is
  * displayed. */
-#define SUG_CLEAN_COUNT	    (SUG_PROMPT_COUNT < 25 ? 25 : SUG_PROMPT_COUNT)
+#define SUG_CLEAN_COUNT(su)    ((su)->su_maxcount < 25 ? 25 : (su)->su_maxcount)
 
 /* 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	    (SUG_PROMPT_COUNT + 50)
+#define SUG_MAX_COUNT(su)    ((su)->su_maxcount + 50)
 
 /* score for various changes */
-#define SCORE_SPLIT	99	/* split bad word */
+#define SCORE_SPLIT	149	/* split bad word */
 #define SCORE_ICASE	52	/* slightly different case */
 #define SCORE_REGION	70	/* word is for different region */
 #define SCORE_RARE	180	/* rare word */
-
-/* score for edit distance */
 #define SCORE_SWAP	90	/* swap two characters */
 #define SCORE_SWAP3	110	/* swap two characters in three */
 #define SCORE_REP	87	/* REP replacement */
@@ -384,6 +399,8 @@
 
 #define SCORE_MAXINIT	350	/* Initial maximum score: higher == slower.
 				 * 350 allows for about three changes. */
+
+#define SCORE_BIG	SCORE_INS * 3	/* big difference */
 #define SCORE_MAXMAX	999999	/* accept any score */
 
 /*
@@ -451,25 +468,26 @@
 #endif
 
 /*
- * For finding suggestion: At each node in the tree these states are tried:
+ * For finding suggestions: At each node in the tree these states are tried:
  */
 typedef enum
 {
-    STATE_START = 0,	/* At start of node, check if word may end or
-			 * split word. */
-    STATE_SPLITUNDO,	/* Undo word split. */
+    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_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,		/* Insert a byte in the bad word. */
     STATE_SWAP,		/* Swap two bytes. */
-    STATE_UNSWAP,	/* Undo swap two bytes. */
-    STATE_SWAP3,	/* Swap two bytes over three. */
-    STATE_UNSWAP3,	/* Undo Swap two bytes over three. */
-    STATE_ROT3L,	/* Rotate three bytes left */
-    STATE_UNROT3L,	/* Undo rotate three bytes left */
-    STATE_ROT3R,	/* Rotate three bytes right */
-    STATE_UNROT3R,	/* Undo rotate three bytes right */
+    STATE_UNSWAP,	/* Undo swap two characters. */
+    STATE_SWAP3,	/* Swap two characters over three. */
+    STATE_UNSWAP3,	/* Undo Swap two characters over three. */
+    STATE_ROT3L,	/* Rotate three characters left */
+    STATE_UNROT3L,	/* Undo rotate three characters left */
+    STATE_ROT3R,	/* Rotate three characters right */
+    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. */
@@ -483,6 +501,7 @@
 {
     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 */
@@ -493,7 +512,6 @@
     char_u	ts_isdiff;	/* DIFF_ values */
     char_u	ts_fcharstart;	/* index in fword where badword char started */
 #endif
-    idx_T	ts_arridx;	/* index in tree array, start of node */
     char_u	ts_save_prewordlen; /* saved "prewordlen" */
     char_u	ts_save_splitoff;   /* su_splitoff saved here */
     char_u	ts_save_badflags;   /* badflags saved here */
@@ -528,30 +546,28 @@
 static int set_spell_chartab __ARGS((char_u *fol, char_u *low, char_u *upp));
 static void write_spell_chartab __ARGS((FILE *fd));
 static int spell_casefold __ARGS((char_u *p, int len, char_u *buf, int buflen));
+static void spell_find_suggest __ARGS((char_u *badptr, suginfo_T *su, int maxcount));
+static void spell_find_cleanup __ARGS((suginfo_T *su));
 static void onecap_copy __ARGS((char_u *word, char_u *wcopy, int upper));
+static void allcap_copy __ARGS((char_u *word, char_u *wcopy));
 static void spell_try_change __ARGS((suginfo_T *su));
 static int try_deeper __ARGS((suginfo_T *su, trystate_T *stack, int depth, int score_add));
 static void find_keepcap_word __ARGS((slang_T *slang, char_u *fword, char_u *kword));
+static void score_comp_sal __ARGS((suginfo_T *su));
+static void score_combine __ARGS((suginfo_T *su));
 static void spell_try_soundalike __ARGS((suginfo_T *su));
 static void make_case_word __ARGS((char_u *fword, char_u *cword, int flags));
 static void set_map_str __ARGS((slang_T *lp, char_u *map));
 static int similar_chars __ARGS((slang_T *slang, int c1, int c2));
-#ifdef RESCORE
-static void add_suggestion __ARGS((suginfo_T *su, char_u *goodword, int use_score, int had_bonus));
-#else
-static void add_suggestion __ARGS((suginfo_T *su, char_u *goodword, int use_score));
-#endif
+static void add_suggestion __ARGS((suginfo_T *su, garray_T *gap, char_u *goodword, int use_score, int had_bonus));
 static void add_banned __ARGS((suginfo_T *su, char_u *word));
 static int was_banned __ARGS((suginfo_T *su, char_u *word));
 static void free_banned __ARGS((suginfo_T *su));
-#ifdef RESCORE
 static void rescore_suggestions __ARGS((suginfo_T *su));
-#endif
-static void cleanup_suggestions __ARGS((suginfo_T *su, int keep));
+static int cleanup_suggestions __ARGS((garray_T *gap, int maxscore, int keep));
 static void spell_soundfold __ARGS((slang_T *slang, char_u *inword, char_u *res));
-#if defined(RESCORE) || defined(SOUNDFOLD_SCORE)
 static int spell_sound_score __ARGS((slang_T *slang, char_u *goodword, char_u	*badsound));
-#endif
+static int soundalike_score __ARGS((char_u *goodsound, char_u *badsound));
 static int spell_edit_score __ARGS((char_u *badword, char_u *goodword));
 
 /*
@@ -617,95 +633,103 @@
 {
     matchinf_T	mi;		/* Most things are put in "mi" so that it can
 				   be passed to functions quickly. */
+    int		nrlen = 0;	/* found a number first */
 
     /* A word never starts at a space or a control character.  Return quickly
      * then, skipping over the character. */
     if (*ptr <= ' ')
 	return 1;
 
-    /* A word starting with a number is always OK.  Also skip hexadecimal
-     * numbers 0xFF99 and 0X99FF. */
+    /* A number is always OK.  Also skip hexadecimal numbers 0xFF99 and
+     * 0X99FF.  But when a word character follows do check spelling. */
     if (*ptr >= '0' && *ptr <= '9')
     {
 	if (*ptr == '0' && (ptr[1] == 'x' || ptr[1] == 'X'))
 	    mi.mi_end = skiphex(ptr + 2);
 	else
+	{
 	    mi.mi_end = skipdigits(ptr);
+	    nrlen = mi.mi_end - ptr;
+	}
+	if (!SPELL_ISWORDP(mi.mi_end))
+	    return (int)(mi.mi_end - ptr);
     }
-    else
+
+    /* Find the end of the word. */
+    mi.mi_word = ptr;
+    mi.mi_fend = ptr;
+
+    if (SPELL_ISWORDP(mi.mi_fend))
     {
-	/* Find the end of the word. */
-	mi.mi_word = ptr;
-	mi.mi_fend = ptr;
-
-	if (SPELL_ISWORDP(mi.mi_fend))
+	/* Make case-folded copy of the characters until the next non-word
+	 * character. */
+	do
 	{
-	    /* Make case-folded copy of the characters until the next non-word
-	     * character. */
-	    do
-	    {
-		mb_ptr_adv(mi.mi_fend);
-	    } while (*mi.mi_fend != NUL && SPELL_ISWORDP(mi.mi_fend));
-	}
-
-	/* We always use the characters up to the next non-word character,
-	 * also for bad words. */
-	mi.mi_end = mi.mi_fend;
-
-	/* Check caps type later. */
-	mi.mi_capflags = 0;
-	mi.mi_cend = NULL;
-
-	/* Include one non-word character so that we can check for the
-	 * word end. */
-	if (*mi.mi_fend != NUL)
 	    mb_ptr_adv(mi.mi_fend);
+	} while (*mi.mi_fend != NUL && SPELL_ISWORDP(mi.mi_fend));
+    }
 
-	(void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
-								 MAXWLEN + 1);
-	mi.mi_fwordlen = STRLEN(mi.mi_fword);
+    /* We always use the characters up to the next non-word character,
+     * also for bad words. */
+    mi.mi_end = mi.mi_fend;
 
-	/* The word is bad unless we recognize it. */
-	mi.mi_result = SP_BAD;
+    /* Check caps type later. */
+    mi.mi_capflags = 0;
+    mi.mi_cend = NULL;
 
-	/*
-	 * Loop over the languages specified in 'spelllang'.
-	 * We check them all, because a matching word may be longer than an
-	 * already found matching word.
-	 */
-	for (mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, 0);
-				       mi.mi_lp->lp_slang != NULL; ++mi.mi_lp)
+    /* Include one non-word character so that we can check for the
+     * word end. */
+    if (*mi.mi_fend != NUL)
+	mb_ptr_adv(mi.mi_fend);
+
+    (void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
+							     MAXWLEN + 1);
+    mi.mi_fwordlen = STRLEN(mi.mi_fword);
+
+    /* The word is bad unless we recognize it. */
+    mi.mi_result = SP_BAD;
+
+    /*
+     * Loop over the languages specified in 'spelllang'.
+     * We check them all, because a matching word may be longer than an
+     * already found matching word.
+     */
+    for (mi.mi_lp = LANGP_ENTRY(wp->w_buffer->b_langp, 0);
+				   mi.mi_lp->lp_slang != NULL; ++mi.mi_lp)
+    {
+	/* Check for a matching word in case-folded words. */
+	find_word(&mi, FIND_FOLDWORD);
+
+	/* Check for a matching word in keep-case words. */
+	find_word(&mi, FIND_KEEPWORD);
+
+	/* Check for matching prefixes. */
+	find_prefix(&mi);
+    }
+
+    if (mi.mi_result != SP_OK)
+    {
+	/* If we found a number skip over it.  Allows for "42nd". */
+	if (nrlen > 0)
+	    return nrlen;
+
+	/* When we are at a non-word character there is no error, just
+	 * skip over the character (try looking for a word after it). */
+	if (!SPELL_ISWORDP(ptr))
 	{
-	    /* Check for a matching word in case-folded words. */
-	    find_word(&mi, FIND_FOLDWORD);
-
-	    /* Check for a matching word in keep-case words. */
-	    find_word(&mi, FIND_KEEPWORD);
-
-	    /* Check for matching prefixes. */
-	    find_prefix(&mi);
-	}
-
-	if (mi.mi_result != SP_OK)
-	{
-	    /* When we are at a non-word character there is no error, just
-	     * skip over the character (try looking for a word after it). */
-	    if (!SPELL_ISWORDP(ptr))
-	    {
 #ifdef FEAT_MBYTE
-		if (has_mbyte)
-		    return mb_ptr2len_check(ptr);
+	    if (has_mbyte)
+		return mb_ptr2len_check(ptr);
 #endif
-		return 1;
-	    }
-
-	    if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
-		*attrp = highlight_attr[HLF_SPB];
-	    else if (mi.mi_result == SP_RARE)
-		*attrp = highlight_attr[HLF_SPR];
-	    else
-		*attrp = highlight_attr[HLF_SPL];
+	    return 1;
 	}
+
+	if (mi.mi_result == SP_BAD || mi.mi_result == SP_BANNED)
+	    *attrp = highlight_attr[HLF_SPB];
+	else if (mi.mi_result == SP_RARE)
+	    *attrp = highlight_attr[HLF_SPR];
+	else
+	    *attrp = highlight_attr[HLF_SPL];
     }
 
     return (int)(mi.mi_end - ptr);
@@ -934,8 +958,8 @@
 		    {
 			regmatch.regprog = rp;
 			regmatch.rm_ic = FALSE;
-			if (!vim_regexec(&regmatch, mip->mi_fword,
-						  (colnr_T)mip->mi_prefixlen))
+			if (!vim_regexec(&regmatch,
+					mip->mi_fword + mip->mi_prefixlen, 0))
 			    continue;
 		    }
 
@@ -1338,7 +1362,7 @@
     {
 	lp->sl_name = vim_strsave(lang);
 	ga_init2(&lp->sl_rep, sizeof(fromto_T), 10);
-	ga_init2(&lp->sl_sal, sizeof(fromto_T), 10);
+	ga_init2(&lp->sl_sal, sizeof(salitem_T), 10);
     }
     return lp;
 }
@@ -1365,7 +1389,7 @@
 {
     garray_T	*gap;
     fromto_T	*ftp;
-    int		round;
+    salitem_T	*smp;
     int		i;
 
     vim_free(lp->sl_fbyts);
@@ -1382,17 +1406,23 @@
     vim_free(lp->sl_pidxs);
     lp->sl_pidxs = NULL;
 
-    for (round = 1; round <= 2; ++round)
+    gap = &lp->sl_rep;
+    while (gap->ga_len > 0)
     {
-	gap = round == 1 ? &lp->sl_rep : &lp->sl_sal;
-	while (gap->ga_len > 0)
-	{
-	    ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
-	    vim_free(ftp->ft_from);
-	    vim_free(ftp->ft_to);
-	}
-	ga_clear(gap);
+	ftp = &((fromto_T *)gap->ga_data)[--gap->ga_len];
+	vim_free(ftp->ft_from);
+	vim_free(ftp->ft_to);
     }
+    ga_clear(gap);
+
+    gap = &lp->sl_sal;
+    while (gap->ga_len > 0)
+    {
+	smp = &((salitem_T *)gap->ga_data)[--gap->ga_len];
+	vim_free(smp->sm_lead);
+	vim_free(smp->sm_to);
+    }
+    ga_clear(gap);
 
     for (i = 0; i < lp->sl_prefixcnt; ++i)
 	vim_free(lp->sl_prefprog[i]);
@@ -1459,9 +1489,11 @@
     slang_T	*lp = NULL;
     garray_T	*gap;
     fromto_T	*ftp;
+    salitem_T	*smp;
     int		rr;
     short	*first;
     idx_T	idx;
+    int		c = 0;
 
     fd = mch_fopen((char *)fname, "r");
     if (fd == NULL)
@@ -1598,7 +1630,8 @@
 	     * compile the regexp program used to check for the condition. */
 	    if (n > 0)
 	    {
-		p = buf;
+		buf[0] = '^';	    /* always match at one position only */
+		p = buf + 1;
 		while (n-- > 0)
 		    *p++ = getc(fd);			/* <condstr> */
 		*p = NUL;
@@ -1612,76 +1645,145 @@
      *             <salflags> <salcount> <sal> ...
      *             <maplen> <mapstr> */
 
-    /*
-     * round 1: rep items
-     * round 2: sal items
-     */
-    for (round = 1; round <= 2; ++round)
+    cnt = (getc(fd) << 8) + getc(fd);			/* <repcount> */
+    if (cnt < 0)
+	goto formerr;
+
+    gap = &lp->sl_rep;
+    if (ga_grow(gap, cnt) == FAIL)
+	goto endFAIL;
+
+    /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
+    for (; gap->ga_len < cnt; ++gap->ga_len)
     {
-	if (round == 1)
+	ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
+	for (rr = 1; rr <= 2; ++rr)
 	{
-	    gap = &lp->sl_rep;
-	    first = lp->sl_rep_first;
+	    ccnt = getc(fd);
+	    if (ccnt < 0)
+	    {
+		if (rr == 2)
+		    vim_free(ftp->ft_from);
+		goto formerr;
+	    }
+	    if ((p = alloc(ccnt + 1)) == NULL)
+	    {
+		if (rr == 2)
+		    vim_free(ftp->ft_from);
+		goto endFAIL;
+	    }
+	    for (i = 0; i < ccnt; ++i)
+		p[i] = getc(fd);		/* <repfrom> or <repto> */
+	    p[i] = NUL;
+	    if (rr == 1)
+		ftp->ft_from = p;
+	    else
+		ftp->ft_to = p;
+	}
+    }
+
+    /* Fill the first-index table. */
+    first = lp->sl_rep_first;
+    for (i = 0; i < 256; ++i)
+	first[i] = -1;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	ftp = &((fromto_T *)gap->ga_data)[i];
+	if (first[*ftp->ft_from] == -1)
+	    first[*ftp->ft_from] = i;
+    }
+
+    i = getc(fd);				/* <salflags> */
+    if (i & SAL_F0LLOWUP)
+	lp->sl_followup = TRUE;
+    if (i & SAL_COLLAPSE)
+	lp->sl_collapse = TRUE;
+    if (i & SAL_REM_ACCENTS)
+	lp->sl_rem_accents = TRUE;
+
+    cnt = (getc(fd) << 8) + getc(fd);		/* <salcount> */
+    if (cnt < 0)
+	goto formerr;
+
+    gap = &lp->sl_sal;
+    if (ga_grow(gap, cnt) == FAIL)
+	goto endFAIL;
+
+    /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */
+    for (; gap->ga_len < cnt; ++gap->ga_len)
+    {
+	smp = &((salitem_T *)gap->ga_data)[gap->ga_len];
+	ccnt = getc(fd);			/* <salfromlen> */
+	if (ccnt < 0)
+	    goto formerr;
+	if ((p = alloc(ccnt + 2)) == NULL)
+	    goto endFAIL;
+	smp->sm_lead = p;
+
+	/* Read up to the first special char into sm_lead. */
+	for (i = 0; i < ccnt; ++i)
+	{
+	    c = getc(fd);			/* <salfrom> */
+	    if (vim_strchr((char_u *)"0123456789(-<^$", c) != NULL)
+		break;
+	    *p++ = c;
+	}
+	smp->sm_leadlen = p - smp->sm_lead;
+	*p++ = NUL;
+
+	/* Put optional chars in sm_oneoff, if any. */
+	if (c == '(')
+	{
+	    smp->sm_oneoff = p;
+	    for (++i; i < ccnt; ++i)
+	    {
+		c = getc(fd);			/* <salfrom> */
+		if (c == ')')
+		    break;
+		*p++ = c;
+	    }
+	    *p++ = NUL;
+	    if (++i < ccnt)
+		c = getc(fd);
 	}
 	else
+	    smp->sm_oneoff = NULL;
+
+	/* Any following chars go in sm_rules. */
+	smp->sm_rules = p;
+	if (i < ccnt)
+	    *p++ = c;
+	for (++i; i < ccnt; ++i)
+	    *p++ = getc(fd);			/* <salfrom> */
+	*p++ = NUL;
+
+	ccnt = getc(fd);			/* <saltolen> */
+	if (ccnt < 0)
 	{
-	    gap = &lp->sl_sal;
-	    first = lp->sl_sal_first;
-
-	    i = getc(fd);				/* <salflags> */
-	    if (i & SAL_F0LLOWUP)
-		lp->sl_followup = TRUE;
-	    if (i & SAL_COLLAPSE)
-		lp->sl_collapse = TRUE;
-	    if (i & SAL_REM_ACCENTS)
-		lp->sl_rem_accents = TRUE;
-	}
-
-	cnt = (getc(fd) << 8) + getc(fd);	/* <repcount> or <salcount> */
-	if (cnt < 0)
+	    vim_free(smp->sm_lead);
 	    goto formerr;
-
-	if (ga_grow(gap, cnt) == FAIL)
+	}
+	if ((p = alloc(ccnt + 1)) == NULL)
+	{
+	    vim_free(smp->sm_lead);
 	    goto endFAIL;
-	for (; gap->ga_len < cnt; ++gap->ga_len)
-	{
-	    /* <rep> : <repfromlen> <repfrom> <reptolen> <repto> */
-	    /* <sal> : <salfromlen> <salfrom> <saltolen> <salto> */
-	    ftp = &((fromto_T *)gap->ga_data)[gap->ga_len];
-	    for (rr = 1; rr <= 2; ++rr)
-	    {
-		ccnt = getc(fd);
-		if (ccnt < 0)
-		{
-		    if (rr == 2)
-			vim_free(ftp->ft_from);
-		    goto formerr;
-		}
-		if ((p = alloc(ccnt + 1)) == NULL)
-		{
-		    if (rr == 2)
-			vim_free(ftp->ft_from);
-		    goto endFAIL;
-		}
-		for (i = 0; i < ccnt; ++i)
-		    p[i] = getc(fd);	/* <repfrom> or <salfrom> */
-		p[i] = NUL;
-		if (rr == 1)
-		    ftp->ft_from = p;
-		else
-		    ftp->ft_to = p;
-	    }
 	}
+	smp->sm_to = p;
 
-	/* Fill the first-index table. */
-	for (i = 0; i < 256; ++i)
-	    first[i] = -1;
-	for (i = 0; i < gap->ga_len; ++i)
-	{
-	    ftp = &((fromto_T *)gap->ga_data)[i];
-	    if (first[*ftp->ft_from] == -1)
-		first[*ftp->ft_from] = i;
-	}
+	for (i = 0; i < ccnt; ++i)
+	    *p++ = getc(fd);			/* <salto> */
+	*p++ = NUL;
+    }
+
+    /* Fill the first-index table. */
+    first = lp->sl_sal_first;
+    for (i = 0; i < 256; ++i)
+	first[i] = -1;
+    for (i = 0; i < gap->ga_len; ++i)
+    {
+	smp = &((salitem_T *)gap->ga_data)[i];
+	if (first[*smp->sm_lead] == -1)
+	    first[*smp->sm_lead] = i;
     }
 
     cnt = (getc(fd) << 8) + getc(fd);		/* <maplen> */
@@ -2509,7 +2611,7 @@
 		    /* Use a new number in the .spl file later, to be able to
 		     * handle multiple .aff files. */
 		    if (aff->af_pfxpostpone)
-			cur_aff->ah_newID = spin->si_newID++;
+			cur_aff->ah_newID = ++spin->si_newID;
 		}
 		else
 		    tp = &aff->af_suff;
@@ -4784,14 +4886,12 @@
 /*
  * "z?": Find badly spelled word under or after the cursor.
  * Give suggestions for the properly spelled word.
- * This is based on the mechanisms of Aspell, but completely reimplemented.
  */
     void
 spell_suggest()
 {
     char_u	*line;
     pos_T	prev_cursor = curwin->w_cursor;
-    int		attr;
     char_u	wcopy[MAXWLEN + 2];
     char_u	*p;
     int		i;
@@ -4799,76 +4899,23 @@
     suginfo_T	sug;
     suggest_T	*stp;
 
-    /*
-     * Find the start of the badly spelled word.
-     */
+    /* Find the start of the badly spelled word. */
     if (spell_move_to(FORWARD, TRUE, TRUE) == FAIL)
     {
 	beep_flush();
 	return;
     }
 
-    /*
-     * Set the info in "sug".
-     */
-    vim_memset(&sug, 0, sizeof(sug));
-    ga_init2(&sug.su_ga, (int)sizeof(suggest_T), 10);
-    hash_init(&sug.su_banned);
+    /* Get the word and its length. */
     line = ml_get_curline();
-    sug.su_badptr = line + curwin->w_cursor.col;
-    sug.su_badlen = spell_check(curwin, sug.su_badptr, &attr);
-    if (sug.su_badlen >= MAXWLEN)
-	sug.su_badlen = MAXWLEN - 1;	/* just in case */
-    vim_strncpy(sug.su_badword, sug.su_badptr, sug.su_badlen);
-    (void)spell_casefold(sug.su_badptr, sug.su_badlen,
-						    sug.su_fbadword, MAXWLEN);
 
-    /* Ban the bad word itself.  It may appear in another region. */
-    add_banned(&sug, sug.su_badword);
-
-    /*
-     * 1. Try inserting/deleting/swapping/changing a letter, use REP entries
-     *    from the .aff file and inserting a space (split the word).
-     *
-     * Set a maximum score to limit the combination of operations that is
-     * tried.
-     */
-    sug.su_maxscore = SCORE_MAXINIT;
-    spell_try_change(&sug);
-
-    /*
-     * 2. Try finding sound-a-like words.
-     *
-     * Only do this when we don't have a lot of suggestions yet, because it's
-     * very slow and often doesn't find new suggestions.
-     */
-    if (sug.su_ga.ga_len < SUG_CLEAN_COUNT)
-    {
-	/* Allow a higher score now. */
-	sug.su_maxscore = SCORE_MAXMAX;
-	spell_try_soundalike(&sug);
-    }
-
-    /* When CTRL-C was hit while searching do show the results. */
-    ui_breakcheck();
-    if (got_int)
-    {
-	(void)vgetc();
-	got_int = FALSE;
-    }
+    /* Get the list of suggestions */
+    spell_find_suggest(line + curwin->w_cursor.col, &sug, (int)Rows - 2);
 
     if (sug.su_ga.ga_len == 0)
 	MSG(_("Sorry, no suggestions"));
     else
     {
-#ifdef RESCORE
-	/* Do slow but more accurate computation of the word score. */
-	rescore_suggestions(&sug);
-#endif
-
-	/* Sort the suggestions and truncate at SUG_PROMPT_COUNT. */
-	cleanup_suggestions(&sug, SUG_PROMPT_COUNT);
-
 	/* List the suggestions. */
 	msg_start();
 	vim_snprintf((char *)IObuff, IOSIZE, _("Change \"%.*s\" to:"),
@@ -4879,7 +4926,7 @@
 	msg_scroll = TRUE;
 	for (i = 0; i < sug.su_ga.ga_len; ++i)
 	{
-	    stp = &SUG(&sug, i);
+	    stp = &SUG(sug.su_ga, i);
 
 	    /* The suggested word may replace only part of the bad word, add
 	     * the not replaced part. */
@@ -4889,8 +4936,17 @@
 					       sug.su_badptr + stp->st_orglen,
 					      sug.su_badlen - stp->st_orglen);
 	    if (p_verbose > 0)
-		vim_snprintf((char *)IObuff, IOSIZE, _("%2d \"%s\"  (%d)"),
+	    {
+		if (sps_flags & SPS_DOUBLE)
+		    vim_snprintf((char *)IObuff, IOSIZE,
+			_("%2d \"%s\"  (%s%d - %d)"),
+			i + 1, wcopy,
+			stp->st_salscore ? "s " : "",
+			stp->st_score, stp->st_altscore);
+		else
+		    vim_snprintf((char *)IObuff, IOSIZE, _("%2d \"%s\"  (%d)"),
 						 i + 1, wcopy, stp->st_score);
+	    }
 	    else
 		vim_snprintf((char *)IObuff, IOSIZE, _("%2d \"%s\""),
 								i + 1, wcopy);
@@ -4901,10 +4957,10 @@
 
 	/* Ask for choice. */
 	i = prompt_for_number();
-	if (i > 0 && i <= sug.su_ga.ga_len && u_save_cursor())
+	if (i > 0 && i <= sug.su_ga.ga_len && u_save_cursor() == OK)
 	{
 	    /* Replace the word. */
-	    stp = &SUG(&sug, i - 1);
+	    stp = &SUG(sug.su_ga, i - 1);
 	    p = alloc(STRLEN(line) - stp->st_orglen + STRLEN(stp->st_word) + 1);
 	    if (p != NULL)
 	    {
@@ -4915,19 +4971,169 @@
 		ml_replace(curwin->w_cursor.lnum, p, FALSE);
 		curwin->w_cursor.col = c;
 		changed_bytes(curwin->w_cursor.lnum, c);
+
+		/* For redo we use a change-word command. */
+		ResetRedobuff();
+		AppendToRedobuff((char_u *)"ciw");
+		AppendToRedobuff(stp->st_word);
+		AppendCharToRedobuff(ESC);
 	    }
 	}
 	else
 	    curwin->w_cursor = prev_cursor;
     }
 
-    /* Free the suggestions. */
+    spell_find_cleanup(&sug);
+}
+
+/*
+ * Find spell suggestions for "word".  Return them in the growarray "*gap" as
+ * a list of allocated strings.
+ */
+    void
+spell_suggest_list(gap, word, maxcount)
+    garray_T	*gap;
+    char_u	*word;
+    int		maxcount;	/* maximum nr of suggestions */
+{
+    suginfo_T	sug;
+    int		i;
+    suggest_T	*stp;
+    char_u	*wcopy;
+
+    spell_find_suggest(word, &sug, maxcount);
+
+    /* 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) == FAIL)
+	return;
+
     for (i = 0; i < sug.su_ga.ga_len; ++i)
-	vim_free(SUG(&sug, i).st_word);
-    ga_clear(&sug.su_ga);
+    {
+	stp = &SUG(sug.su_ga, i);
+
+	/* The suggested word may replace only part of "word", add the not
+	 * replaced part. */
+	wcopy = alloc(STRLEN(stp->st_word)
+				+ STRLEN(sug.su_badptr + stp->st_orglen) + 1);
+	if (wcopy == NULL)
+	    break;
+	STRCPY(wcopy, stp->st_word);
+	STRCAT(wcopy, 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(badptr, su, maxcount)
+    char_u	*badptr;
+    suginfo_T	*su;
+    int		maxcount;
+{
+    int		attr;
+
+    /*
+     * 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);
+    hash_init(&su->su_banned);
+
+    su->su_badptr = badptr;
+    su->su_badlen = spell_check(curwin, su->su_badptr, &attr);
+    su->su_maxcount = maxcount;
+
+    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);
+
+    /* Ban the bad word itself.  It may appear in another region. */
+    add_banned(su, su->su_badword);
+
+    /*
+     * 1. Try inserting/deleting/swapping/changing a letter, use REP entries
+     *    from the .aff file and inserting a space (split the word).
+     *
+     * Set a maximum score to limit the combination of operations that is
+     * tried.
+     */
+    su->su_maxscore = SCORE_MAXINIT;
+    spell_try_change(su);
+
+    /* For the resulting top-scorers compute the sound-a-like score. */
+    if (sps_flags & SPS_DOUBLE)
+	score_comp_sal(su);
+
+    /*
+     * 2. Try finding sound-a-like words.
+     *
+     * Only do this when we don't have a lot of suggestions yet, because it's
+     * very slow and often doesn't find new suggestions.
+     */
+    if ((sps_flags & SPS_DOUBLE)
+	    || (!(sps_flags & SPS_FAST)
+				    && su->su_ga.ga_len < SUG_CLEAN_COUNT(su)))
+    {
+	/* Allow a higher score now. */
+	su->su_maxscore = SCORE_MAXMAX;
+	spell_try_soundalike(su);
+    }
+
+    /* When CTRL-C was hit while searching do show the results. */
+    ui_breakcheck();
+    if (got_int)
+    {
+	(void)vgetc();
+	got_int = FALSE;
+    }
+
+    if (sps_flags & SPS_DOUBLE)
+    {
+	/* Combine the two list of suggestions. */
+	score_combine(su);
+    }
+    else if (su->su_ga.ga_len != 0)
+    {
+	if (sps_flags & SPS_BEST)
+	    /* Adjust the word score for how it sounds like. */
+	    rescore_suggestions(su);
+
+	/* Sort the suggestions and truncate at "maxcount". */
+	(void)cleanup_suggestions(&su->su_ga, su->su_maxscore, maxcount);
+    }
+}
+
+/*
+ * Free the info put in "*su" by spell_find_suggest().
+ */
+    static void
+spell_find_cleanup(su)
+    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. */
-    free_banned(&sug);
+    free_banned(su);
 }
 
 /*
@@ -5058,13 +5264,6 @@
     for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0);
 						   lp->lp_slang != NULL; ++lp)
     {
-#ifdef SOUNDFOLD_SCORE
-	su->su_slang = lp->lp_slang;
-	if (lp->lp_slang->sl_sal.ga_len > 0)
-	    /* soundfold the bad word */
-	    spell_soundfold(lp->lp_slang, su->su_fbadword, su->su_salword);
-#endif
-
 	/*
 	 * Go through the whole case-fold tree, try changes at each node.
 	 * "tword[]" contains the word collected from nodes in the tree.
@@ -5160,11 +5359,8 @@
 		if (fword[sp->ts_fidx] == 0)
 		{
 		    /* The badword also ends: add suggestions, */
-		    add_suggestion(su, preword, sp->ts_score + newscore
-#ifdef RESCORE
-			    , FALSE
-#endif
-			    );
+		    add_suggestion(su, &su->su_ga, preword,
+					      sp->ts_score + newscore, FALSE);
 		}
 		else if (sp->ts_fidx >= sp->ts_fidxtry
 #ifdef FEAT_MBYTE
@@ -5757,9 +5953,10 @@
 	    default:
 		/* Did all possible states at this level, go up one level. */
 		--depth;
-	    }
 
-	    line_breakcheck();
+		/* Don't check for CTRL-C too often, it takes time. */
+		line_breakcheck();
+	    }
 	}
     }
 }
@@ -5950,6 +6147,168 @@
 }
 
 /*
+ * Compute the sound-a-like score for suggestions in su->su_ga and add them to
+ * su->su_sga.
+ */
+    static void
+score_comp_sal(su)
+    suginfo_T	*su;
+{
+    langp_T	*lp;
+    char_u	badsound[MAXWLEN];
+    int		i;
+    suggest_T   *stp;
+    suggest_T   *sstp;
+    char_u	fword[MAXWLEN];
+    char_u	goodsound[MAXWLEN];
+    int		score;
+
+    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 (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0);
+						   lp->lp_slang != NULL; ++lp)
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    /* soundfold the bad word */
+	    spell_soundfold(lp->lp_slang, su->su_fbadword, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+
+		/* Case-fold the suggested word and sound-fold it. */
+		(void)spell_casefold(stp->st_word, STRLEN(stp->st_word),
+							      fword, MAXWLEN);
+		spell_soundfold(lp->lp_slang, fword, goodsound);
+		score = soundalike_score(goodsound, 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_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 intwined.
+ */
+    static void
+score_combine(su)
+    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];
+    char_u	goodsound[MAXWLEN];
+    char_u	fword[MAXWLEN];
+    int		round;
+
+    /* Add the alternate score to su_ga. */
+    for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0);
+						   lp->lp_slang != NULL; ++lp)
+    {
+	if (lp->lp_slang->sl_sal.ga_len > 0)
+	{
+	    /* soundfold the bad word */
+	    spell_soundfold(lp->lp_slang, su->su_fbadword, badsound);
+
+	    for (i = 0; i < su->su_ga.ga_len; ++i)
+	    {
+		stp = &SUG(su->su_ga, i);
+
+		/* Case-fold the word, sound-fold the word and compute the
+		 * score for the difference. */
+		(void)spell_casefold(stp->st_word, STRLEN(stp->st_word),
+							  fword, MAXWLEN);
+		spell_soundfold(lp->lp_slang, fword, goodsound);
+		stp->st_altscore = soundalike_score(goodsound, 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;
+	}
+    }
+
+    /* 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(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;
+    }
+
+    /* Sort the suggestions and truncate at "maxcount" for both lists. */
+    (void)cleanup_suggestions(&su->su_ga, su->su_maxscore, su->su_maxcount);
+    (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;
+}
+
+/*
  * Find suggestions by comparing the word in a sound-a-like form.
  */
     static void
@@ -5970,9 +6329,9 @@
     idx_T	n;
     int		round;
     int		flags;
-    int		score, sound_score;
-    char_u	*bp, *sp;
+    int		sound_score;
 
+    /* Do this for all languages that support sound folding. */
     for (lp = LANGP_ENTRY(curwin->w_buffer->b_langp, 0);
 						   lp->lp_slang != NULL; ++lp)
     {
@@ -6033,40 +6392,15 @@
 							    tfword, tsalword);
 				}
 
-				/*
-				 * Accept the word if the sound-folded words
-				 * are (almost) equal.
-				 */
-				for (bp = salword, sp = tsalword; *bp == *sp;
-								   ++bp, ++sp)
-				    if (*bp == NUL)
-					break;
-
-				if (*bp == *sp)
-				    /* equal */
-				    sound_score = 0;
-				else if (*bp != NUL && bp[1] != NUL
-					&& *bp == sp[1] && bp[1] == *sp
-					       && STRCMP(bp + 2, sp + 2) == 0)
-				    /* swap two bytes */
-				    sound_score = SCORE_SWAP;
-				else if (STRCMP(bp + 1, sp) == 0)
-				    /* delete byte */
-				    sound_score = SCORE_DEL;
-				else if (STRCMP(bp, sp + 1) == 0)
-				    /* insert byte */
-				    sound_score = SCORE_INS;
-				else if (STRCMP(bp + 1, sp + 1) == 0)
-				    /* skip one byte */
-				    sound_score = SCORE_SUBST;
-				else
-				    /* not equal or similar */
-				    sound_score = SCORE_MAXMAX;
-
+				/* Compute the edit distance between the
+				 * sound-a-like words. */
+				sound_score = soundalike_score(salword,
+								    tsalword);
 				if (sound_score < SCORE_MAXMAX)
 				{
 				    char_u	cword[MAXWLEN];
 				    char_u	*p;
+				    int		score;
 
 				    if (round == 1 && flags != 0)
 				    {
@@ -6078,18 +6412,25 @@
 				    else
 					p = tword;
 
-				    /* Compute the score. */
-				    score = spell_edit_score(su->su_badword, p);
-#ifdef RESCORE
-				    /* give a bonus for the good word sounding
-				     * the same as the bad word */
-				    add_suggestion(su, tword,
-						 RESCORE(score, sound_score),
+				    if (sps_flags & SPS_DOUBLE)
+					add_suggestion(su, &su->su_sga, p,
+							  sound_score, FALSE);
+				    else
+				    {
+					/* Compute the score. */
+					score = spell_edit_score(
+							   su->su_badword, p);
+					if (sps_flags & SPS_BEST)
+					    /* give a bonus for the good word
+					     * sounding the same as the bad
+					     * word */
+					    add_suggestion(su, &su->su_ga, p,
+						  RESCORE(score, sound_score),
 									TRUE);
-#else
-				    add_suggestion(su, tword,
-							 score + sound_score);
-#endif
+					else
+					    add_suggestion(su, &su->su_ga, p,
+						  score + sound_score, FALSE);
+				    }
 				}
 			    }
 
@@ -6275,24 +6616,15 @@
  * with spell_edit_score().
  */
     static void
-add_suggestion(su, goodword, score
-#ifdef RESCORE
-	    , had_bonus
-#endif
-	    )
+add_suggestion(su, gap, goodword, score, had_bonus)
     suginfo_T	*su;
+    garray_T	*gap;
     char_u	*goodword;
     int		score;
-#ifdef RESCORE
-    int		had_bonus;	/* set st_had_bonus */
-#endif
+    int		had_bonus;	/* value for st_had_bonus */
 {
     suggest_T   *stp;
     int		i;
-#ifdef SOUNDFOLD_SCORE
-    char_u	fword[MAXWLEN];
-    char_u	salword[MAXWLEN];
-#endif
 
     /* Check that the word wasn't banned. */
     if (was_banned(su, goodword))
@@ -6300,47 +6632,38 @@
 
     if (score <= su->su_maxscore)
     {
-#ifdef SOUNDFOLD_SCORE
-	/* Add to the score when the word sounds differently.
-	 * This is slow... */
-	if (su->su_slang->sl_sal.ga_len > 0)
-	    score += spell_sound_score(su->su_slang, fword, su->su_salword);
-#endif
-
 	/* Check if the word is already there. */
-	stp = &SUG(su, 0);
-	for (i = su->su_ga.ga_len - 1; i >= 0; --i)
+	stp = &SUG(*gap, 0);
+	for (i = gap->ga_len - 1; i >= 0; --i)
 	    if (STRCMP(stp[i].st_word, goodword) == 0)
 	    {
 		/* Found it.  Remember the lowest score. */
 		if (stp[i].st_score > score)
 		{
 		    stp[i].st_score = score;
-#ifdef RESCORE
 		    stp[i].st_had_bonus = had_bonus;
-#endif
 		}
 		break;
 	    }
 
-	if (i < 0 && ga_grow(&su->su_ga, 1) == OK)
+	if (i < 0 && ga_grow(gap, 1) == OK)
 	{
 	    /* Add a suggestion. */
-	    stp = &SUG(su, su->su_ga.ga_len);
+	    stp = &SUG(*gap, gap->ga_len);
 	    stp->st_word = vim_strsave(goodword);
 	    if (stp->st_word != NULL)
 	    {
 		stp->st_score = score;
-#ifdef RESCORE
+		stp->st_altscore = 0;
 		stp->st_had_bonus = had_bonus;
-#endif
 		stp->st_orglen = su->su_badlen;
-		++su->su_ga.ga_len;
+		++gap->ga_len;
 
 		/* If we have too many suggestions now, sort the list and keep
 		 * the best suggestions. */
-		if (su->su_ga.ga_len > SUG_MAX_COUNT)
-		    cleanup_suggestions(su, SUG_CLEAN_COUNT);
+		if (gap->ga_len > SUG_MAX_COUNT(su))
+		    su->su_maxscore = cleanup_suggestions(gap, su->su_maxscore,
+							 SUG_CLEAN_COUNT(su));
 	    }
 	}
     }
@@ -6402,7 +6725,6 @@
     hash_clear(&su->su_banned);
 }
 
-#ifdef RESCORE
 /*
  * Recompute the score if sound-folding is possible.  This is slow,
  * thus only done for the final results.
@@ -6427,7 +6749,7 @@
 
 	    for (i = 0; i < su->su_ga.ga_len; ++i)
 	    {
-		stp = &SUG(su, i);
+		stp = &SUG(su->su_ga, i);
 		if (!stp->st_had_bonus)
 		{
 		    score = spell_sound_score(lp->lp_slang, stp->st_word,
@@ -6439,7 +6761,6 @@
 	}
     }
 }
-#endif
 
 static int
 #ifdef __BORLANDC__
@@ -6460,35 +6781,40 @@
 {
     suggest_T	*p1 = (suggest_T *)s1;
     suggest_T	*p2 = (suggest_T *)s2;
+    int		n = p1->st_score - p2->st_score;
 
-    return p1->st_score - p2->st_score;
+    if (n == 0)
+	return p1->st_altscore - p2->st_altscore;
+    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 void
-cleanup_suggestions(su, keep)
-    suginfo_T	*su;
+    static int
+cleanup_suggestions(gap, maxscore, keep)
+    garray_T	*gap;
+    int		maxscore;
     int		keep;		/* nr of suggestions to keep */
 {
-    suggest_T   *stp = &SUG(su, 0);
+    suggest_T   *stp = &SUG(*gap, 0);
     int		i;
 
     /* Sort the list. */
-    qsort(su->su_ga.ga_data, (size_t)su->su_ga.ga_len,
-					      sizeof(suggest_T), sug_compare);
+    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 (su->su_ga.ga_len > keep)
+    if (gap->ga_len > keep)
     {
-	for (i = keep; i < su->su_ga.ga_len; ++i)
+	for (i = keep; i < gap->ga_len; ++i)
 	    vim_free(stp[i].st_word);
-	su->su_ga.ga_len = keep;
-	su->su_maxscore = stp[keep - 1].st_score;
+	gap->ga_len = keep;
+	return stp[keep - 1].st_score;
     }
+    return maxscore;
 }
 
 /*
@@ -6500,7 +6826,7 @@
     char_u	*inword;
     char_u	*res;
 {
-    fromto_T	*ftp;
+    salitem_T	*smp;
     char_u	word[MAXWLEN];
 #ifdef FEAT_MBYTE
     int		l;
@@ -6508,7 +6834,9 @@
 #endif
     char_u	*s;
     char_u	*t;
+    char_u	*pf;
     int		i, j, z;
+    int		reslen;
     int		n, k = 0;
     int		z0;
     int		k0;
@@ -6526,7 +6854,10 @@
 	for (s = inword; *s != NUL; )
 	{
 	    if (vim_iswhite(*s))
-		*t++ = *s++;
+	    {
+		*t++ = ' ';
+		s = skipwhite(s);
+	    }
 #ifdef FEAT_MBYTE
 	    else if (has_mbyte)
 	    {
@@ -6574,55 +6905,53 @@
     }
 #endif
 
-    ftp = (fromto_T *)slang->sl_sal.ga_data;
+    smp = (salitem_T *)slang->sl_sal.ga_data;
 
     /*
      * This comes from Aspell phonet.cpp.  Converted from C++ to C.
      * Changed to keep spaces.
      * TODO: support for multi-byte chars.
      */
-    i = j = z = 0;
+    i = reslen = z = 0;
     while ((c = word[i]) != NUL)
     {
+	/* Start with the first rule that has the character in the word. */
 	n = slang->sl_sal_first[c];
 	z0 = 0;
 
 	if (n >= 0)
 	{
 	    /* check all rules for the same letter */
-	    while (ftp[n].ft_from[0] == c)
+	    for (; (s = smp[n].sm_lead)[0] == c; ++n)
 	    {
-		/* check whole string */
-		k = 1;   /* number of found letters */
-		pri = 5;   /* default priority */
-		s = ftp[n].ft_from;
-		s++;     /* important for (see below)  "*(s-1)" */
-
-		/* Skip over normal letters that match with the word. */
-		while (*s != NUL && word[i + k] == *s
-			&& !vim_isdigit(*s) && strchr("(-<^$", *s) == NULL)
+		/* Quickly skip entries that don't match the word.  Most
+		 * entries are less then three chars, optimize for that. */
+		k = smp[n].sm_leadlen;
+		if (k > 1)
 		{
-		    k++;
-		    s++;
+		    if (word[i + 1] != s[1])
+			continue;
+		    if (k > 2)
+		    {
+			for (j = 2; j < k; ++j)
+			    if (word[i + j] != s[j])
+				break;
+			if (j < k)
+			    continue;
+		    }
 		}
 
-		if (*s == '(')
+		if ((pf = smp[n].sm_oneoff) != NULL)
 		{
-		    /* check alternate letters in "(..)" */
-		    for (t = s + 1; *t != ')' && *t != NUL; ++t)
-			if (*t == word[i + k])
-			{
-			    /* match */
-			    ++k;
-			    for (s = t + 1; *s != NUL; ++s)
-				if (*s == ')')
-				{
-				    ++s;
-				    break;
-				}
-			    break;
-			}
+		    /* Check for match with one of the chars in "sm_oneoff". */
+		    while (*pf != NUL && *pf != word[i + k])
+			++pf;
+		    if (*pf == NUL)
+			continue;
+		    ++k;
 		}
+		s = smp[n].sm_rules;
+		pri = 5;    /* default priority */
 
 		p0 = *s;
 		k0 = k;
@@ -6633,7 +6962,7 @@
 		}
 		if (*s == '<')
 		    s++;
-		if (vim_isdigit(*s))
+		if (VIM_ISDIGIT(*s))
 		{
 		    /* determine priority */
 		    pri = *s - '0';
@@ -6658,50 +6987,52 @@
 		    n0 = slang->sl_sal_first[c0];
 
 		    if (slang->sl_followup && k > 1 && n0 >= 0
-			    && p0 != '-' && word[i + k] != NUL)
+					   && p0 != '-' && word[i + k] != NUL)
 		    {
 			/* test follow-up rule for "word[i + k]" */
-			while (ftp[n0].ft_from[0] == c0)
+			for ( ; (s = smp[n0].sm_lead)[0] == c0; ++n0)
 			{
+			    /* Quickly skip entries that don't match the word.
+			     * */
+			    k0 = smp[n0].sm_leadlen;
+			    if (k0 > 1)
+			    {
+				if (word[i + k] != s[1])
+				    continue;
+				if (k0 > 2)
+				{
+				    pf = word + i + k + 1;
+				    for (j = 2; j < k0; ++j)
+					if (*pf++ != s[j])
+					    break;
+				    if (j < k0)
+					continue;
+				}
+			    }
+			    k0 += k - 1;
 
-			    /* check whole string */
-			    k0 = k;
+			    if ((pf = smp[n0].sm_oneoff) != NULL)
+			    {
+				/* Check for match with one of the chars in
+				 * "sm_oneoff". */
+				while (*pf != NUL && *pf != word[i + k0])
+				    ++pf;
+				if (*pf == NUL)
+				    continue;
+				++k0;
+			    }
+
 			    p0 = 5;
-			    s = ftp[n0].ft_from;
-			    s++;
-			    while (*s != NUL && word[i+k0] == *s
-				    && !vim_isdigit(*s)
-						&& strchr("(-<^$",*s) == NULL)
-			    {
-				k0++;
-				s++;
-			    }
-			    if (*s == '(')
-			    {
-				/* check alternate letters in "(..)" */
-				for (t = s + 1; *t != ')' && *t != NUL; ++t)
-				    if (*t == word[i + k0])
-				    {
-					/* match */
-					++k0;
-					for (s = t + 1; *s != NUL; ++s)
-					    if (*s == ')')
-					    {
-						++s;
-						break;
-					    }
-					break;
-				    }
-			    }
+			    s = smp[n0].sm_rules;
 			    while (*s == '-')
 			    {
-				/* "k0" gets NOT reduced  */
-				/* because "if (k0 == k)" */
+				/* "k0" gets NOT reduced because
+				 * "if (k0 == k)" */
 				s++;
 			    }
 			    if (*s == '<')
 				s++;
-			    if (vim_isdigit(*s))
+			    if (VIM_ISDIGIT(*s))
 			    {
 				p0 = *s - '0';
 				s++;
@@ -6713,42 +7044,31 @@
 					    && !SPELL_ISWORDP(word + i + k0)))
 			    {
 				if (k0 == k)
-				{
 				    /* this is just a piece of the string */
-				    ++n0;
 				    continue;
-				}
 
 				if (p0 < pri)
-				{
 				    /* priority too low */
-				    ++n0;
 				    continue;
-				}
 				/* rule fits; stop search */
 				break;
 			    }
-			    ++n0;
 			}
 
-			if (p0 >= pri && ftp[n0].ft_from[0] == c0)
-			{
-			    ++n;
+			if (p0 >= pri && smp[n0].sm_lead[0] == c0)
 			    continue;
-			}
 		    }
 
 		    /* replace string */
-		    s = ftp[n].ft_to;
-		    p0 = (ftp[n].ft_from[0] != NUL
-			    && vim_strchr(ftp[n].ft_from + 1,
-							'<') != NULL) ? 1 : 0;
+		    s = smp[n].sm_to;
+		    pf = smp[n].sm_rules;
+		    p0 = (vim_strchr(pf, '<') != NULL) ? 1 : 0;
 		    if (p0 == 1 && z == 0)
 		    {
 			/* rule with '<' is used */
-			if (j > 0 && *s != NUL
-				&& (res[j - 1] == c || res[j - 1] == *s))
-			    j--;
+			if (reslen > 0 && *s != NUL && (res[reslen - 1] == c
+						    || res[reslen - 1] == *s))
+			    reslen--;
 			z0 = 1;
 			z = 1;
 			k0 = 0;
@@ -6770,25 +7090,23 @@
 			/* no '<' rule used */
 			i += k - 1;
 			z = 0;
-			while (*s != NUL && s[1] != NUL && j < MAXWLEN)
+			while (*s != NUL && s[1] != NUL && reslen < MAXWLEN)
 			{
-			    if (j == 0 || res[j - 1] != *s)
+			    if (reslen == 0 || res[reslen - 1] != *s)
 			    {
-				res[j] = *s;
-				j++;
+				res[reslen] = *s;
+				reslen++;
 			    }
 			    s++;
 			}
 			/* new "actual letter" */
 			c = *s;
-			if (ftp[n].ft_from[0] != NUL
-					 && strstr((char *)ftp[n].ft_from + 1,
-								"^^") != NULL)
+			if (strstr((char *)pf, "^^") != NULL)
 			{
 			    if (c != NUL)
 			    {
-				res[j] = c;
-				j++;
+				res[reslen] = c;
+				reslen++;
 			    }
 			    mch_memmove(word, word + i + 1,
 						    STRLEN(word + i + 1) + 1);
@@ -6798,7 +7116,6 @@
 		    }
 		    break;
 		}
-		++n;
 	    }
 	}
 	else if (vim_iswhite(c))
@@ -6809,12 +7126,13 @@
 
 	if (z0 == 0)
 	{
-	    if (k && !p0 && j < MAXWLEN && c != NUL
-		    && (!slang->sl_collapse || j == 0 || res[j - 1] != c))
+	    if (k && !p0 && reslen < MAXWLEN && c != NUL
+		    && (!slang->sl_collapse || reslen == 0
+						     || res[reslen - 1] != c))
 	    {
 		/* condense only double letters */
-		res[j] = c;
-		j++;
+		res[reslen] = c;
+		reslen++;
 	    }
 
 	    i++;
@@ -6823,10 +7141,9 @@
 	}
     }
 
-    res[j] = NUL;
+    res[reslen] = NUL;
 }
 
-#if defined(RESCORE) || defined(SOUNDFOLD_SCORE)
 /*
  * Return the score for how much words sound different.
  */
@@ -6840,13 +7157,14 @@
     char_u	goodsound[MAXWLEN];
     int		score;
 
-    /* Case-fold the word, needed for sound folding. */
+    /* Case-fold the goodword, needed for sound folding. */
     (void)spell_casefold(goodword, STRLEN(goodword), fword, MAXWLEN);
 
-    /* sound-fold the good word */
+    /* sound-fold the goodword */
     spell_soundfold(slang, fword, goodsound);
 
-    /* compute the edit distance-score of the sounds */
+    /* Compute the edit distance-score of the sounds.  This is slow but we
+     * only do it for a small number of words. */
     score = spell_edit_score(badsound, goodsound);
 
     /* Correction: adding/inserting "*" at the start (word starts with vowel)
@@ -6857,11 +7175,207 @@
 
     return score;
 }
-#endif
+
+/*
+ * 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(goodsound, badsound)
+    char_u	*goodsound;	/* sound-folded good word */
+    char_u	*badsound;	/* sound-folded bad word */
+{
+    int		goodlen = STRLEN(goodsound);
+    int		badlen = STRLEN(badsound);
+    int		n;
+    char_u	*pl, *ps;
+    char_u	*pl2, *ps2;
+
+    /* Return quickly if the lenghts 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;	    /* longest */
+	ps = badsound;
+    }
+    else
+    {
+	pl = badsound;	    /* 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_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_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_DEL + SCORE_SWAP;
+
+	    /* 3: delete then substitute, then the rest must be equal */
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return 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_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_SUBST + SCORE_DEL;
+
+	    /* Failed to compare. */
+	    break;
+
+	case 0:
+	    /*
+	     * Lenghts 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 0;
+
+	    /* 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_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_SWAP + SCORE_SWAP;
+
+		/* 4: swap and substitute */
+		if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		    return SCORE_SWAP + SCORE_SUBST;
+	    }
+
+	    /* 5: substitute */
+	    pl2 = pl + 1;
+	    ps2 = ps + 1;
+	    while (*pl2 == *ps2)
+	    {
+		if (*pl2 == NUL)	/* reached the end */
+		    return 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_SUBST + SCORE_SWAP;
+
+	    /* 7: substitute and substitute */
+	    if (STRCMP(pl2 + 1, ps2 + 1) == 0)
+		return 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_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_INS + SCORE_DEL;
+
+	    /* Failed to compare. */
+	    break;
+    }
+
+    return SCORE_MAXMAX;
+}
 
 /*
  * Compute the "edit distance" to turn "badword" into "goodword".  The less
- * deletes/inserts/swaps are required the lower the score.
+ * deletes/inserts/substitutes/swaps are required the lower the score.
  *
  * The algorithm comes from Aspell editdist.cpp, edit_distance().
  * It has been converted from C++ to C and modified to support multi-byte
@@ -6969,7 +7483,10 @@
 	    }
 	}
     }
-    return CNT(badlen - 1, goodlen - 1);
+
+    i = CNT(badlen - 1, goodlen - 1);
+    vim_free(cnt);
+    return i;
 }
 
 #endif  /* FEAT_SYN_HL */
diff --git a/src/spell/Makefile b/src/spell/Makefile
index 2ff2850..838e603 100644
--- a/src/spell/Makefile
+++ b/src/spell/Makefile
@@ -46,6 +46,9 @@
 	
 	-diff -a -C 1 fr_FR.orig.aff fr_FR.aff >fr_FR.diff
 	-diff -a -C 1 fr_FR.orig.dic fr_FR.dic >>fr_FR.diff
+	
+	-diff -a -C 1 he_IL.orig.aff he_IL.aff >he_IL.diff
+	-diff -a -C 1 he_IL.orig.dic he_IL.dic >>he_IL.diff
 
 $(SPELLDIR)/en.latin1.spl : $(VIM) \
 			en_US.aff en_US.dic \
diff --git a/src/spell/de_DE.diff b/src/spell/de_DE.diff
new file mode 100644
index 0000000..8940e44
--- /dev/null
+++ b/src/spell/de_DE.diff
@@ -0,0 +1,22 @@
+*** de_DE.orig.aff	Fri Jun 17 10:01:18 2005
+--- de_DE.aff	Sat Jun 18 19:46:19 2005
+***************
+*** 3,4 ****
+--- 3,8 ----
+  
++ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
++ 
+  # (c) copyright by Bjoern Jacke <bjoern@j3e.de>
+*** de_DE.orig.dic	Fri Jun 17 10:01:27 2005
+--- de_DE.dic	Sat Jun 18 19:57:07 2005
+***************
+*** 76258,76259 ****
+  zynismusfördernd/A
+! zzgl
+\ No newline at end of file
+--- 76258,76260 ----
+  zynismusfördernd/A
+! zzgl
+! 
diff --git a/src/spell/en_AU.diff b/src/spell/en_AU.diff
index 2d03fa8..d78f557 100644
--- a/src/spell/en_AU.diff
+++ b/src/spell/en_AU.diff
@@ -1,5 +1,5 @@
 *** en_AU.orig.aff	Fri Apr 15 13:20:36 2005
---- en_AU.aff	Sat Apr 23 19:57:40 2005
+--- en_AU.aff	Sat Jun 18 19:42:07 2005
 ***************
 *** 7,9 ****
   SET ISO8859-1
@@ -9,9 +9,9 @@
   SET ISO8859-1
 ! TRY esiaénrtolcdugmphbyfvkw-'.zqjxSNRTLCGDMPHBEAUYOFIVKWöâôZQJXÅçèîêàïüäñ
 ! 
-! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
+! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 ! 
 ! 
   REP 24
@@ -2227,49 +2227,161 @@
 ! SFX 3 o ist's o
 ! SFX 3 0 ist's [^eoy]
 *** en_AU.orig.dic	Fri Apr 15 13:20:36 2005
---- en_AU.dic	Tue Apr 19 22:19:18 2005
+--- en_AU.dic	Tue Jun 21 20:24:15 2005
+***************
+*** 912,914 ****
+  Alaska/M
+! al/AY
+  albacore/MS
+--- 912,914 ----
+  Alaska/M
+! really
+  albacore/MS
+***************
+*** 4885,4887 ****
+  bozo/SM
+- b/pb
+  bpi
+--- 4885,4886 ----
 ***************
 *** 4921,4922 ****
---- 4921,4923 ----
+--- 4920,4922 ----
   Brahms
 + Bram/M
   braid/DGS
 ***************
+*** 10288,10289 ****
+--- 10288,10292 ----
+  dB/M
++ dBi
++ dBm
++ dBd
+  DBMS
+***************
 *** 12468,12469 ****
---- 12469,12471 ----
+--- 12471,12473 ----
   Dutch/5m
 + Farsi
   Dutchwomen/M
 ***************
+*** 13779,13781 ****
+  estuary/MS
+! et
+  ETA
+--- 13783,13786 ----
+  estuary/MS
+! et cetera
+! et al.
+  ETA
+***************
 *** 19214,19216 ****
   Hobbes
 ! hobbit
   hobble/RGSD
---- 19216,19218 ----
+--- 19219,19221 ----
   Hobbes
 ! hobbit/MS
   hobble/RGSD
 ***************
+*** 22885,22887 ****
+  lass/SM
+- last-ditch
+  lasted/e
+--- 22890,22891 ----
+***************
+*** 22890,22892 ****
+  last/kJYDSG
+- last-minute
+  lasts/e
+--- 22894,22895 ----
+***************
 *** 26417,26418 ****
---- 26419,26421 ----
+--- 26420,26422 ----
   Moolawatana
 + Moolenaar/M
   Moomba
 ***************
+*** 27188,27192 ****
+  nationals/4
+! national/sQq3S
+  nationhood/M
+! nation/M
+  nationwide
+--- 27192,27196 ----
+  nationals/4
+! national/sQq3SZ
+  nationhood/M
+! nation/MS
+  nationwide
+***************
+*** 27194,27195 ****
+--- 27198,27201 ----
+  nativity/MS
++ natively
++ nativeness
+  NATO/M
+***************
+*** 31035,31037 ****
+  Pk
+- p/KF
+  pl.
+--- 31041,31042 ----
+***************
+*** 31288,31289 ****
+--- 31293,31295 ----
+  pneumonia/MS
++ pneumonic
+  PO
+***************
+*** 31460,31461 ****
+--- 31466,31468 ----
+  pompom/MS
++ pompon/M
+  pomposity/MS
+***************
+*** 33378,33380 ****
+  razzmatazz
+- r/d
+  Rd/M
+--- 33385,33386 ----
+***************
+*** 34979,34981 ****
+  RSPCA
+- rte
+  rub-a-dub
+--- 34985,34986 ----
+***************
 *** 36012,36014 ****
   sec.
 ! s/eca
   secant/MS
---- 36015,36017 ----
+--- 36017,36019 ----
   sec.
 ! outs
   secant/MS
 ***************
+*** 42616,42618 ****
+  Tyson/M
+- u
+  ubiquitousness
+--- 42621,42622 ----
+***************
+*** 42990,42991 ****
+--- 42994,42996 ----
+  unscrupulous
++ searchable
+  unsearchable
+***************
 *** 43749,43751 ****
   Vilnius/M
 ! vim/M
   vinaigrette/MS
---- 43752,43754 ----
+--- 43754,43756 ----
   Vilnius/M
 ! Vim/M
   vinaigrette/MS
+***************
+*** 45655 ****
+--- 45660,45661 ----
+  zymurgy/S
++ nd
diff --git a/src/spell/en_CA.diff b/src/spell/en_CA.diff
index c321ff1..62e7213 100644
--- a/src/spell/en_CA.diff
+++ b/src/spell/en_CA.diff
@@ -1,12 +1,12 @@
 *** en_CA.orig.aff	Fri Apr 15 13:20:36 2005
---- en_CA.aff	Sat Apr 23 19:57:43 2005
+--- en_CA.aff	Sat Jun 18 19:42:19 2005
 ***************
 *** 3,4 ****
 --- 3,8 ----
   
-+ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
++ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 + 
   PFX A Y 1
 ***************
@@ -39,7 +39,7 @@
 ! SFX G   0     ing        [^e]
   
 *** en_CA.orig.dic	Sat Apr 16 14:40:06 2005
---- en_CA.dic	Tue Apr 19 22:19:46 2005
+--- en_CA.dic	Tue Jun 21 20:25:01 2005
 ***************
 *** 46,48 ****
   R/G
@@ -47,32 +47,150 @@
   easternmost
 --- 46,47 ----
 ***************
-*** 89,91 ****
-  r/GVTJ
+*** 59,61 ****
+  a
+! b/KGDT
+  Emmey/M
+--- 58,61 ----
+  a
+! probing
+! probed
+  Emmey/M
+***************
+*** 82,84 ****
+  m/XG
+! n/FKT
+  o
+--- 82,84 ----
+  m/XG
+! pron
+  o
+***************
+*** 86,91 ****
+  fitting/PSY
+- p/KRT
+  q
+! r/GVTJ
 ! s/FK
   fatting
---- 88,90 ----
-  r/GVTJ
+--- 86,89 ----
+  fitting/PSY
+  q
 ! cons
   fatting
 ***************
+*** 94,96 ****
+  oedipal
+- u
+  v/VTK
+--- 92,93 ----
+***************
+*** 3145,3146 ****
+--- 3142,3144 ----
+  semester/MS
++ etc.
+  etch/GZSRDJ
+***************
+*** 7022,7024 ****
+  DA
+- DB
+  DC
+--- 7020,7021 ----
+***************
+*** 8388,8390 ****
+  slotting
+- ON
+  OR
+--- 8385,8386 ----
+***************
+*** 9125,9127 ****
+  perchance
+- rte
+  hastiness/MS
+--- 9121,9122 ----
+***************
+*** 10603,10604 ****
+--- 10598,10602 ----
+  dB/M
++ dBi
++ dBm
++ dBd
+  Hewet/M
+***************
+*** 10615,10617 ****
+  Garold/M
+- db
+  tollhouse/M
+--- 10613,10614 ----
+***************
+*** 11017,11019 ****
+  hr
+- ht
+  MCI/M
+--- 11014,11015 ----
+***************
+*** 11609,11611 ****
+  demureness/SM
+! nd/A
+  MIA
+--- 11605,11607 ----
+  demureness/SM
+! nd
+  MIA
+***************
 *** 13669,13671 ****
   engross/LDRSG
 ! hobbit
   certainty/MUS
---- 13668,13670 ----
+--- 13665,13667 ----
   engross/LDRSG
 ! hobbit/MS
   certainty/MUS
 ***************
+*** 14434,14435 ****
+--- 14430,14432 ----
+  pompom/MS
++ pompon/M
+  Devland/M
+***************
+*** 19265,19267 ****
+  bloodstone/M
+! cetera/S
+  storm/SGZRDM
+--- 19262,19264 ----
+  bloodstone/M
+! et cetera/S
+  storm/SGZRDM
+***************
+*** 20162,20164 ****
+  Hansel/M
+! ring/GZJDRM
+  Hansen/M
+--- 20159,20161 ----
+  Hansel/M
+! ring/GZJDRMS
+  Hansen/M
+***************
+*** 28157,28158 ****
+--- 28154,28156 ----
+  pneumonia/MS
++ pneumonic
+  Socratic/S
+***************
+*** 34999,35001 ****
+  claque/MS
+- etc
+  Chad/M
+--- 34997,34998 ----
+***************
 *** 36707,36708 ****
---- 36706,36708 ----
+--- 36704,36706 ----
   Moody/M
 + Moolenaar/M
   Bresenham/M
 ***************
 *** 50272,50273 ****
---- 50272,50274 ----
+--- 50270,50272 ----
   Dutch/M
 + Farsi
   Sharon/M
@@ -81,7 +199,18 @@
   hatchery/MS
 ! vim/SM
   compatriot/MS
---- 52566,52568 ----
+--- 52564,52566 ----
   hatchery/MS
 ! Vim/SM
   compatriot/MS
+***************
+*** 53490,53491 ****
+--- 53489,53491 ----
+  unsearchable
++ searchable
+  felicitous/IY
+***************
+*** 62341 ****
+--- 62341,62342 ----
+  data/M
++ et al.
diff --git a/src/spell/en_GB.diff b/src/spell/en_GB.diff
index 7f7ec13..42fdc5d 100644
--- a/src/spell/en_GB.diff
+++ b/src/spell/en_GB.diff
@@ -1,5 +1,5 @@
 *** en_GB.orig.aff	Fri Apr 15 13:20:36 2005
---- en_GB.aff	Sat Apr 23 19:57:46 2005
+--- en_GB.aff	Sat Jun 18 19:42:24 2005
 ***************
 *** 7,9 ****
   SET ISO8859-1
@@ -9,9 +9,9 @@
   SET ISO8859-1
 ! TRY esiaénrtolcdugmphbyfvkw-'.zqjxSNRTLCGDMPHBEAUYOFIVKWöâôZQJXÅçèîêàïüäñ
 ! 
-! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
+! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 ! 
   REP 24
 ***************
@@ -2226,38 +2226,130 @@
 ! SFX 3 o ist's o
 ! SFX 3 0 ist's [^eoy]
 *** en_GB.orig.dic	Sun Apr 17 18:08:50 2005
---- en_GB.dic	Tue Apr 19 22:20:16 2005
+--- en_GB.dic	Tue Jun 21 20:26:11 2005
+***************
+*** 187,189 ****
+  aitch/SM
+- al/FAC
+  al-Jazeera
+--- 187,188 ----
+***************
+*** 2148,2150 ****
+  dazzle/DRkGJS
+- dBm
+  DC
+--- 2147,2148 ----
+***************
+*** 4637,4639 ****
+  lass/MS
+- last-minute
+  lasts/e
+--- 4635,4636 ----
+***************
+*** 5470,5472 ****
+  Münchhausen/M
+- n/NxnVvu
+  N'Djamena
+--- 5467,5468 ----
+***************
+*** 5499,5501 ****
+  natch
+! nation/M
+  nationalises/A
+--- 5495,5497 ----
+  natch
+! nation/MS
+  nationalises/A
+***************
+*** 6316,6317 ****
+--- 6312,6314 ----
+  pompom/SM
++ pompon/M
+  ponce/M
 ***************
 *** 7048,7050 ****
   régime/SM
 ! s/ok7
   Saab/M
---- 7048,7050 ----
+--- 7045,7047 ----
   régime/SM
 ! singly
   Saab/M
 ***************
+*** 11148,11149 ****
+--- 11145,11148 ----
+  dBi
++ dBm
++ dBd
+  DCB
+***************
+*** 14591,14592 ****
+--- 14590,14592 ----
+  native/SP
++ natively
+  nativity/SM
+***************
+*** 16172,16174 ****
+  RSPCA
+- rte
+  rubati
+--- 16172,16173 ----
+***************
+*** 17808,17809 ****
+--- 17807,17809 ----
+  unsearchable
++ searchable
+  unshakable/Y
+***************
+*** 18322,18323 ****
+--- 18322,18324 ----
+  émigré/S
++ nd
+  3GPP
+***************
 *** 19303,19304 ****
---- 19303,19305 ----
+--- 19304,19306 ----
   Brampton/M
 + Bram/M
   brand/MRDGSZ
 ***************
+*** 21097,21099 ****
+  estimative
+! et
+  etalon
+--- 21099,21102 ----
+  estimative
+! et cetera
+! et al.
+  etalon
+***************
 *** 23632,23633 ****
---- 23633,23635 ----
+--- 23635,23637 ----
   Moog
 + Moolenaar/M
   moonlight/GRDSM
 ***************
+*** 24242,24244 ****
+  oxygenation/M
+- p/FYAI
+  Pablo/M
+--- 24246,24247 ----
+***************
 *** 27223,27225 ****
   Villiers
 ! vim/M
   Vinci/M
---- 27225,27227 ----
+--- 27226,27228 ----
   Villiers
 ! Vim/M
   Vinci/M
 ***************
+*** 28174,28176 ****
+  Aztec/M
+- b/bp
+  Baal/M
+--- 28177,28178 ----
+***************
 *** 31409,31411 ****
   hob/MDGZS
 ! hobbit
@@ -2266,3 +2358,21 @@
   hob/MDGZS
 ! hobbit/MS
   Hobbs
+***************
+*** 32174,32176 ****
+  lasso/GMDS
+- last-ditch
+  Laszlo/M
+--- 32176,32177 ----
+***************
+*** 43275,43276 ****
+--- 43276,43278 ----
+  pneumonia/MS
++ pneumonic
+  PO
+***************
+*** 43665,43667 ****
+  qwerty
+- r/d
+  Ra
+--- 43667,43668 ----
diff --git a/src/spell/en_NZ.diff b/src/spell/en_NZ.diff
index 4fa638b..243018f 100644
--- a/src/spell/en_NZ.diff
+++ b/src/spell/en_NZ.diff
@@ -1,5 +1,5 @@
 *** en_NZ.orig.aff	Fri Apr 15 13:20:36 2005
---- en_NZ.aff	Sat Apr 23 19:57:49 2005
+--- en_NZ.aff	Sat Jun 18 19:42:31 2005
 ***************
 *** 7,9 ****
   SET ISO8859-1
@@ -9,9 +9,9 @@
   SET ISO8859-1
 ! TRY esiaénrtolcdugmphbyfvkw-'.zqjxSNRTLCGDMPHBEAUYOFIVKWöâôZQJXÅçèîêàïüäñ
 ! 
-! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
+! FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
+! UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 ! 
   REP 66
 ***************
@@ -2227,17 +2227,32 @@
 ! SFX 3 o ist's o
 ! SFX 3 0 ist's [^eoy]
 *** en_NZ.orig.dic	Fri Apr 15 13:20:36 2005
---- en_NZ.dic	Sun Apr 17 18:08:55 2005
+--- en_NZ.dic	Tue Jun 21 20:14:24 2005
+***************
+*** 1,6 ****
+  47141
+- 3GPP
+- 2YA
+- 2ZB
+- A
+  a/o
+--- 1,2 ----
+***************
+*** 927,929 ****
+  Al-Zawahiri
+- al/FAC
+  Al/M
+--- 923,924 ----
 ***************
 *** 2941,2944 ****
   B.Sc.
 - bless
 - bible
   baa/GSD
---- 2941,2942 ----
+--- 2936,2937 ----
 ***************
 *** 4974,4975 ****
---- 4972,4974 ----
+--- 4967,4969 ----
   Brampton/M
 + Bram/M
   bran/SDGM
@@ -2246,7 +2261,7 @@
   C.Lit.
 ! cation/SM
   Ca/y
---- 5706,5708 ----
+--- 5701,5703 ----
   C.Lit.
 ! cation/MWS
   Ca/y
@@ -2255,16 +2270,22 @@
   Cathy
 - cation/MW
   catkin/SM
---- 6449,6450 ----
+--- 6444,6445 ----
 ***************
 *** 10153,10155 ****
   red's
 - dally
   dab/TSGD
---- 10151,10152 ----
+--- 10146,10147 ----
+***************
+*** 10360,10361 ****
+--- 10352,10354 ----
+  dBm
++ dBd
+  DBMS
 ***************
 *** 12535,12536 ****
---- 12532,12534 ----
+--- 12528,12530 ----
   Dutchwomen/M
 + Farsi
   duteous/Y
@@ -2273,20 +2294,30 @@
   duvet/SM
 - duxes
   DVD/MS
---- 12540,12541 ----
+--- 12536,12537 ----
+***************
+*** 13901,13903 ****
+  estuary/MS
+! et
+  ETA
+--- 13894,13897 ----
+  estuary/MS
+! et cetera
+! et al.
+  ETA
 ***************
 *** 14531,14534 ****
   f-stop/S
 - fable
 - fist/MS
   fa/M
---- 14528,14529 ----
+--- 14525,14526 ----
 ***************
 *** 15323,15325 ****
   fissure/DSMG
 ! fist/6GD
   fistfight/MS
---- 15318,15320 ----
+--- 15315,15317 ----
   fissure/DSMG
 ! fist/6GDMS
   fistfight/MS
@@ -2295,37 +2326,44 @@
   g's
 - gable
   gist/MS
---- 16601,16602 ----
+--- 16598,16599 ----
 ***************
 *** 16797,16799 ****
   Garvey
 - Gary/M
   gas-permeable
---- 16791,16792 ----
+--- 16788,16789 ----
 ***************
 *** 18177,18179 ****
   gyroscope/SWM
 - dish
   ha
---- 18170,18171 ----
+--- 18167,18168 ----
 ***************
 *** 22321,22323 ****
   K-factor
 - disk/MS
   kabob's
---- 22313,22314 ----
+--- 22310,22311 ----
+***************
+*** 23129,23132 ****
+  lassoer/M
+- last-ditch
+- last-minute
+  last/YSDGkJ
+--- 23117,23118 ----
 ***************
 *** 26396,26398 ****
   Missy
 ! mist/CDRGS
   mistakable/U
---- 26387,26389 ----
+--- 26382,26384 ----
   Missy
 ! mist/CDRGSM
   mistakable/U
 ***************
 *** 26745,26746 ****
---- 26736,26738 ----
+--- 26731,26733 ----
   Moog
 + Moolenaar/M
   moon/MGpDS
@@ -2334,7 +2372,7 @@
   mozzarella/SM
 - MP3
   mpg
---- 27010,27011 ----
+--- 27005,27006 ----
 ***************
 *** 27365,27372 ****
   N'Djamena
@@ -2345,7 +2383,7 @@
 - national
 - nationally
   Na/M
---- 27356,27360 ----
+--- 27351,27355 ----
   N'Djamena
 ! native/SP
   natively
@@ -2356,7 +2394,7 @@
   Nathaniel/M
 ! nation/M
   national/sQ3Sq
---- 27495,27497 ----
+--- 27490,27492 ----
   Nathaniel/M
 ! nation/MS
   national/sQ3Sq
@@ -2365,7 +2403,7 @@
   nationwide
 - native/SP
   nativity/SM
---- 27509,27510 ----
+--- 27504,27505 ----
 ***************
 *** 29852,29857 ****
   P.O.
@@ -2374,27 +2412,57 @@
 - imply
 - comply
   pa/oM
---- 29839,29840 ----
+--- 29834,29835 ----
+***************
+*** 31702,31703 ****
+--- 31680,31682 ----
+  pneumonia/MS
++ pneumonic
+  PO
+***************
+*** 31885,31886 ****
+--- 31864,31866 ----
+  pompom/SM
++ pompon/M
+  pomposity/SM
+***************
+*** 33561,33563 ****
+  qwertys
+- r/d
+  Ra
+--- 33541,33542 ----
+***************
+*** 35456,35458 ****
+  rt
+- rte
+  Ru/M
+--- 35435,35436 ----
 ***************
 *** 35619,35622 ****
   singly
 - sable
 - sally/DSG
   SA
---- 35602,35603 ----
+--- 35597,35598 ----
 ***************
 *** 40763,40766 ****
   T's
 - mist/MS
 - overt
   Ta
---- 40744,40745 ----
+--- 40739,40740 ----
+***************
+*** 43574,43575 ****
+--- 43548,43550 ----
+  unsearchable
++ searchable
+  unseeing/Y
 ***************
 *** 44334,44336 ****
   Vilnius/M
 ! vim/M
   vinaigrette/MS
---- 44313,44315 ----
+--- 44309,44311 ----
   Vilnius/M
 ! Vim/M
   vinaigrette/MS
@@ -2403,66 +2471,73 @@
   y'all
 - prey/M
   yacht/M5SmGD
---- 45885,45886 ----
+--- 45881,45882 ----
 ***************
 *** 46198,46200 ****
   rata/M
 - kaka/M
   waka/M
---- 46176,46177 ----
+--- 46172,46173 ----
 ***************
 *** 46216,46218 ****
   jandal/MS
 - Swanndri/M
   hoon/MS
---- 46193,46194 ----
+--- 46189,46190 ----
 ***************
 *** 46242,46244 ****
   Invercargill/M
 - Te
   Alexandra/M
---- 46218,46219 ----
+--- 46214,46215 ----
 ***************
 *** 46261,46263 ****
   Kawerau/M
 - Kerikeri/M
   Lyttelton/M
---- 46236,46237 ----
+--- 46232,46233 ----
 ***************
 *** 46491,46493 ****
   Waianakarua
 - Hakatere
   Swin
---- 46465,46466 ----
+--- 46461,46462 ----
 ***************
 *** 46690,46692 ****
   Omarama/M
 - Wairarapa/M
   Kilda/M
---- 46663,46664 ----
+--- 46659,46660 ----
 ***************
 *** 46711,46713 ****
   Wellsford/M
 - Akaroa/M
   Avonhead/M
---- 46683,46684 ----
+--- 46679,46680 ----
+***************
+*** 46838,46840 ****
+  Ballantyne's
+- DB
+  Monteith's
+--- 46805,46806 ----
 ***************
 *** 46920,46922 ****
   Egmont/M
 - Waitaki/M
   katipo/M
---- 46891,46892 ----
+--- 46886,46887 ----
 ***************
 *** 46956,46958 ****
   Sunnyside/M
 - Wairau/M
   Waikoropupu
---- 46926,46927 ----
+--- 46921,46922 ----
 ***************
 *** 47141,47142 ****
   Burkina
 ! Faso/M
 \ No newline at end of file
---- 47110,47111 ----
+--- 47105,47107 ----
   Burkina
 ! Faso/M
+! nd
diff --git a/src/spell/en_US.diff b/src/spell/en_US.diff
index be26dfa..460fa4e 100644
--- a/src/spell/en_US.diff
+++ b/src/spell/en_US.diff
@@ -1,12 +1,14 @@
 *** en_US.orig.aff	Fri Apr 15 13:20:36 2005
---- en_US.aff	Sat Apr 23 19:57:52 2005
+--- en_US.aff	Tue Jun 21 20:46:52 2005
 ***************
 *** 3,4 ****
---- 3,8 ----
+--- 3,10 ----
   
-+ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
++ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
++ 
++ RAR ?
 + 
   PFX A Y 1
 ***************
@@ -15,7 +17,7 @@
 ! SFX N   y     ication    y 
 ! SFX N   0     en         [^ey] 
   
---- 34,37 ----
+--- 36,39 ----
   SFX N   e     ion        e
 ! SFX N   y     ication    y
 ! SFX N   0     en         [^ey]
@@ -25,7 +27,7 @@
   SFX H   y     ieth       y
 ! SFX H   0     th         [^y] 
   
---- 44,46 ----
+--- 46,48 ----
   SFX H   y     ieth       y
 ! SFX H   0     th         [^y]
   
@@ -34,69 +36,334 @@
   SFX G   e     ing        e
 ! SFX G   0     ing        [^e] 
   
---- 51,53 ----
+--- 53,55 ----
   SFX G   e     ing        e
 ! SFX G   0     ing        [^e]
   
+***************
+*** 137,138 ****
+--- 143,146 ----
+  REP uy i
++ REP y ie
++ REP ie y
+  REP i ee
+***************
+*** 188 ****
+--- 196,317 ----
+  REP shun cion
++ 
++ MAP 5
++ MAP aàáâãäå
++ MAP eèéêë
++ MAP iìíîï
++ MAP oòóôõö
++ MAP uùúûü
++ MAP nñ
++ MAP cç
++ MAP yÿý
++ MAP sß
++ 
++ # This comes from Aspell en_phonet.dat, version 1.1, 2000-01-07
++ 
++ SAL AH(AEIOUY)-^         *H
++ SAL AR(AEIOUY)-^         *R
++ SAL A(HR)^               *
++ SAL A^                   *
++ SAL AH(AEIOUY)-          H
++ SAL AR(AEIOUY)-          R
++ SAL A(HR)                _
++ SAL À^                   *
++ SAL Å^                   *
++ SAL BB-                  _
++ SAL B                    B
++ SAL CQ-                  _
++ SAL CIA                  X
++ SAL CH                   X
++ SAL C(EIY)-              S
++ SAL CK                   K
++ SAL COUGH^               KF
++ SAL CC<                  C
++ SAL C                    K
++ SAL DG(EIY)              K
++ SAL DD-                  _
++ SAL D                    T
++ SAL É<                   E
++ SAL EH(AEIOUY)-^         *H
++ SAL ER(AEIOUY)-^         *R
++ SAL E(HR)^               *
++ SAL ENOUGH^$             *NF
++ SAL E^                   *
++ SAL EH(AEIOUY)-          H
++ SAL ER(AEIOUY)-          R
++ SAL E(HR)                _
++ SAL FF-                  _
++ SAL F                    F
++ SAL GN^                  N
++ SAL GN$                  N
++ SAL GNS$                 NS
++ SAL GNED$                N
++ SAL GH(AEIOUY)-          K
++ SAL GH                   _
++ SAL GG9                  K
++ SAL G                    K
++ SAL H                    H
++ SAL IH(AEIOUY)-^         *H
++ SAL IR(AEIOUY)-^         *R
++ SAL I(HR)^               *
++ SAL I^                   *
++ SAL ING6                 N
++ SAL IH(AEIOUY)-          H
++ SAL IR(AEIOUY)-          R
++ SAL I(HR)                _
++ SAL J                    K
++ SAL KN^                  N
++ SAL KK-                  _
++ SAL K                    K
++ SAL LAUGH^               LF
++ SAL LL-                  _
++ SAL L                    L
++ SAL MB$                  M
++ SAL MM                   M
++ SAL M                    M
++ SAL NN-                  _
++ SAL N                    N
++ SAL OH(AEIOUY)-^         *H
++ SAL OR(AEIOUY)-^         *R
++ SAL O(HR)^               *
++ SAL O^                   *
++ SAL OH(AEIOUY)-          H
++ SAL OR(AEIOUY)-          R
++ SAL O(HR)                _
++ SAL PH                   F
++ SAL PN^                  N
++ SAL PP-                  _
++ SAL P                    P
++ SAL Q                    K
++ SAL RH^                  R
++ SAL ROUGH^               RF
++ SAL RR-                  _
++ SAL R                    R
++ SAL SCH(EOU)-            SK
++ SAL SC(IEY)-             S
++ SAL SH                   X
++ SAL SI(AO)-              X
++ SAL SS-                  _
++ SAL S                    S
++ SAL TI(AO)-              X
++ SAL TH                   @
++ SAL TCH--                _
++ SAL TOUGH^               TF
++ SAL TT-                  _
++ SAL T                    T
++ SAL UH(AEIOUY)-^         *H
++ SAL UR(AEIOUY)-^         *R
++ SAL U(HR)^               *
++ SAL U^                   *
++ SAL UH(AEIOUY)-          H
++ SAL UR(AEIOUY)-          R
++ SAL U(HR)                _
++ SAL V^                   W
++ SAL V                    F
++ SAL WR^                  R
++ SAL WH^                  W
++ SAL W(AEIOU)-            W
++ SAL X^                   S
++ SAL X                    KS
++ SAL Y(AEIOU)-            Y
++ SAL ZZ-                  _
++ SAL Z                    S
 *** en_US.orig.dic	Fri Apr 15 13:20:36 2005
---- en_US.dic	Tue Apr 19 23:08:36 2005
+--- en_US.dic	Tue Jun 21 20:26:22 2005
+***************
+*** 5944,5946 ****
+  bk
+! b/KGD
+  Bk/M
+--- 5944,5947 ----
+  bk
+! probing
+! probed
+  Bk/M
+***************
+*** 9233,9235 ****
+  cetacean/S
+- cetera/S
+  Cetus/M
+--- 9234,9235 ----
+***************
+*** 14038,14043 ****
+  dazzling/Y
+- db
+- DB
+  dbl
+  dB/M
+  DBMS
+--- 14038,14044 ----
+  dazzling/Y
+  dbl
+  dB/M
++ dBi
++ dBm
++ dBd
+  DBMS
 ***************
 *** 16911,16912 ****
---- 16911,16913 ----
+--- 16912,16914 ----
   dusty/RPT
 + Farsi
   Dutch/M
 ***************
+*** 18780,18782 ****
+  estuary/SM
+! et
+  ET
+--- 18782,18785 ----
+  estuary/SM
+! et cetera/S
+! et al.
+  ET
+***************
+*** 18785,18787 ****
+  eta/SM
+! etc
+  etcetera/SM
+--- 18788,18790 ----
+  eta/SM
+! etc.
+  etcetera/SM
+***************
 *** 25963,25965 ****
   hobbing
 ! hobbit
   hobbler/M
---- 25964,25966 ----
+--- 25966,25968 ----
   hobbing
 ! hobbit/MS
   hobbler/M
 ***************
+*** 26524,26526 ****
+  HST
+- ht
+  HTML
+--- 26527,26528 ----
+***************
+*** 34746,34747 ****
+--- 34748,34751 ----
+  Mb
++ Mbyte
++ Mbit
+  MB
+***************
 *** 36605,36606 ****
---- 36606,36608 ----
+--- 36609,36611 ----
   Moog
 + Moolenaar/M
   moo/GSD
 ***************
 *** 38871,38873 ****
   NSF
-! n/T
+- n/T
   NT
---- 38873,38875 ----
-  NSF
-! n
-  NT
+--- 38876,38877 ----
+***************
+*** 39532,39534 ****
+  om/XN
+- ON
+  onanism/M
+--- 39536,39537 ----
+***************
+*** 42508,42510 ****
+  pinfeather/SM
+! ping/GDRM
+  pinheaded/P
+--- 42511,42513 ----
+  pinfeather/SM
+! ping/GDRMS
+  pinheaded/P
+***************
+*** 42983,42984 ****
+--- 42986,42988 ----
+  pneumonia/MS
++ pneumonic
+  PO
+***************
+*** 43216,43218 ****
+  pompom/SM
+! pompon's
+  pomposity/MS
+--- 43220,43222 ----
+  pompom/SM
+! pompon/M
+  pomposity/MS
+***************
+*** 44940,44942 ****
+  PX
+- p/XTGJ
+  Pygmalion/M
+--- 44944,44945 ----
 ***************
 *** 46507,46509 ****
   Renault/MS
 - rend
   renderer/M
---- 46509,46510 ----
+--- 46510,46511 ----
+***************
+*** 47258,47260 ****
+  ringer/M
+! ring/GZJDRM
+  ringing/Y
+--- 47260,47262 ----
+  ringer/M
+! ring/GZJDRMS
+  ringing/Y
+***************
+*** 47857,47862 ****
+  rt
+- rte
+  Rte
+  RTFM
+- r/TGVJ
+  Rubaiyat/M
+--- 47859,47862 ----
 ***************
 *** 48085,48087 ****
   Ryun/M
 - S
   SA
---- 48086,48087 ----
+--- 48085,48086 ----
 ***************
 *** 54450,54452 ****
   swung
 ! s/XJBG
   sybarite/MS
---- 54450,54452 ----
+--- 54449,54451 ----
   swung
 ! sings
   sybarite/MS
 ***************
+*** 57809,57811 ****
+  Tzeltal/M
+- u
+  U
+--- 57808,57809 ----
+***************
+*** 58494,58495 ****
+--- 58492,58494 ----
+  unsearchable
++ searchable
+  unseasonal
+***************
 *** 59538,59540 ****
   vi/MDR
 ! vim/MS
   vinaigrette/MS
---- 59538,59540 ----
+--- 59537,59539 ----
   vi/MDR
 ! Vim/MS
   vinaigrette/MS
+***************
+*** 62077 ****
+--- 62076,62078 ----
+  zymurgy/S
++ the the/?
++ nd
diff --git a/src/spell/fr_FR.diff b/src/spell/fr_FR.diff
index 0c955de..1c02728 100644
--- a/src/spell/fr_FR.diff
+++ b/src/spell/fr_FR.diff
@@ -1,11 +1,11 @@
 *** fr_FR.orig.aff	Sun Apr 14 17:18:22 2002
---- fr_FR.aff	Sat Apr 23 19:57:26 2005
+--- fr_FR.aff	Sat Jun 18 19:43:02 2005
 ***************
 *** 3,4 ****
 --- 3,8 ----
   
-+ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
++ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 + 
   PFX A Y 10
diff --git a/src/spell/he_IL.diff b/src/spell/he_IL.diff
new file mode 100644
index 0000000..0dfde43
--- /dev/null
+++ b/src/spell/he_IL.diff
@@ -0,0 +1,10 @@
+*** he_IL.orig.aff	Sat Jun 18 14:46:51 2005
+--- he_IL.aff	Sat Jun 18 15:13:34 2005
+***************
+*** 2,3 ****
+--- 2,6 ----
+  TRY éåäàòçë÷'"ùñæãâáøðîèöúôíóêõïì
++ 
++ PFXPOSTPONE
++ 
+  # This file was generated automatically from data prepared
diff --git a/src/spell/nl_NL.diff b/src/spell/nl_NL.diff
index cdc3146..f6a8f08 100644
--- a/src/spell/nl_NL.diff
+++ b/src/spell/nl_NL.diff
@@ -1,12 +1,12 @@
 *** nl_NL.orig.aff	Wed Apr 20 11:48:16 2005
---- nl_NL.aff	Sat Apr 23 16:48:27 2005
+--- nl_NL.aff	Tue Jun 21 11:08:32 2005
 ***************
 *** 3,4 ****
 --- 3,8 ----
   
-+ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
++ FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþß
++ UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞß
 + 
   NOSPLITSUGS
 ***************
@@ -111,43 +111,380 @@
 ! REP kontekst context
 ! REP korrekt correct
   REP kritikus criticus
+***************
+*** 333 ****
+--- 337,458 ----
+  REP aflassen afgelasten
++ 
++ MAP 5
++ MAP aàáâãäå
++ MAP eèéêë
++ MAP iìíîï
++ MAP oòóôõö
++ MAP uùúûü
++ MAP nñ
++ MAP cç
++ MAP yÿý
++ MAP sß
++ 
++ # This comes from Aspell en_phonet.dat, version 1.1, 2000-01-07
++ 
++ SAL AH(AEIOUY)-^         *H
++ SAL AR(AEIOUY)-^         *R
++ SAL A(HR)^               *
++ SAL A^                   *
++ SAL AH(AEIOUY)-          H
++ SAL AR(AEIOUY)-          R
++ SAL A(HR)                _
++ SAL À^                   *
++ SAL Å^                   *
++ SAL BB-                  _
++ SAL B                    B
++ SAL CQ-                  _
++ SAL CIA                  X
++ SAL CH                   X
++ SAL C(EIY)-              S
++ SAL CK                   K
++ SAL COUGH^               KF
++ SAL CC<                  C
++ SAL C                    K
++ SAL DG(EIY)              K
++ SAL DD-                  _
++ SAL D                    T
++ SAL É<                   E
++ SAL EH(AEIOUY)-^         *H
++ SAL ER(AEIOUY)-^         *R
++ SAL E(HR)^               *
++ SAL ENOUGH^$             *NF
++ SAL E^                   *
++ SAL EH(AEIOUY)-          H
++ SAL ER(AEIOUY)-          R
++ SAL E(HR)                _
++ SAL FF-                  _
++ SAL F                    F
++ SAL GN^                  N
++ SAL GN$                  N
++ SAL GNS$                 NS
++ SAL GNED$                N
++ SAL GH(AEIOUY)-          K
++ SAL GH                   _
++ SAL GG9                  K
++ SAL G                    K
++ SAL H                    H
++ SAL IH(AEIOUY)-^         *H
++ SAL IR(AEIOUY)-^         *R
++ SAL I(HR)^               *
++ SAL I^                   *
++ SAL ING6                 N
++ SAL IH(AEIOUY)-          H
++ SAL IR(AEIOUY)-          R
++ SAL I(HR)                _
++ SAL J                    K
++ SAL KN^                  N
++ SAL KK-                  _
++ SAL K                    K
++ SAL LAUGH^               LF
++ SAL LL-                  _
++ SAL L                    L
++ SAL MB$                  M
++ SAL MM                   M
++ SAL M                    M
++ SAL NN-                  _
++ SAL N                    N
++ SAL OH(AEIOUY)-^         *H
++ SAL OR(AEIOUY)-^         *R
++ SAL O(HR)^               *
++ SAL O^                   *
++ SAL OH(AEIOUY)-          H
++ SAL OR(AEIOUY)-          R
++ SAL O(HR)                _
++ SAL PH                   F
++ SAL PN^                  N
++ SAL PP-                  _
++ SAL P                    P
++ SAL Q                    K
++ SAL RH^                  R
++ SAL ROUGH^               RF
++ SAL RR-                  _
++ SAL R                    R
++ SAL SCH(EOU)-            SK
++ SAL SC(IEY)-             S
++ SAL SH                   X
++ SAL SI(AO)-              X
++ SAL SS-                  _
++ SAL S                    S
++ SAL TI(AO)-              X
++ SAL TH                   @
++ SAL TCH--                _
++ SAL TOUGH^               TF
++ SAL TT-                  _
++ SAL T                    T
++ SAL UH(AEIOUY)-^         *H
++ SAL UR(AEIOUY)-^         *R
++ SAL U(HR)^               *
++ SAL U^                   *
++ SAL UH(AEIOUY)-          H
++ SAL UR(AEIOUY)-          R
++ SAL U(HR)                _
++ SAL V^                   W
++ SAL V                    F
++ SAL WR^                  R
++ SAL WH^                  W
++ SAL W(AEIOU)-            W
++ SAL X^                   S
++ SAL X                    KS
++ SAL Y(AEIOU)-            Y
++ SAL ZZ-                  _
++ SAL Z                    S
 *** nl_NL.orig.dic	Tue Apr 19 21:03:15 2005
---- nl_NL.dic	Wed Apr 20 18:47:07 2005
+--- nl_NL.dic	Wed Jun 15 10:36:20 2005
+***************
+*** 8,9 ****
+--- 8,11 ----
+  's-Hertogenbosch
++ fietsstandaard
++ fietslantaarn
+  A4
 ***************
 *** 91,93 ****
   Athene
 - Athene
   Atjees/E
---- 91,92 ----
+--- 93,94 ----
 ***************
 *** 216,217 ****
---- 215,218 ----
+--- 217,220 ----
   Brussels/E
 + BTW
 + B.T.W.
   Budel
 ***************
 *** 325,326 ****
---- 326,328 ----
+--- 328,330 ----
   Duurstede
 + DVD
   Dwingeloo
 ***************
-*** 813,814 ****
---- 815,817 ----
-  Montfort
-+ Moolenaar/X
-  Moordrecht
+*** 7485,7486 ****
+--- 7489,7493 ----
+  avond/SN
++ 's avonds
++ 's middags
++ 's ochtends
+  avondappèl/S
+***************
+*** 20681,20682 ****
+--- 20688,20690 ----
+  cytostatica
++ d.m.v.
+  daad/P
 ***************
 *** 46300,46301 ****
---- 46303,46305 ----
+--- 46308,46310 ----
   informaticus
 + informatie/S
   informatie-uitwisseling
 ***************
-*** 60206,60207 ****
---- 60210,60213 ----
+*** 60206,60208 ****
+--- 60215,60222 ----
   löss
 + m.a.w.
 + m.b.t.
++ m.n.
   ma/JW
++ mm
++ mg
+  maag
+***************
+*** 97474,97475 ****
+--- 97488,97490 ----
+  suïciderisico/X
++ s.v.p.
+  swagger/S
+***************
+*** 101428,101429 ****
+--- 101443,101446 ----
+  toezichthouder/S
++ toezichthoudersaansprakelijkheidsverzekering
++ toezichthoudersaansprakelijkheidsverzekeringen
+  toezie/N
+***************
+*** 103707,103708 ****
+--- 103724,103726 ----
+  tête-à-tête/S
++ u
+  uchtend/N
+***************
+*** 119938 ****
+--- 119956,120126 ----
+  überhaupt
++ Christiaan/X
++ Fred/X
++ Jansen/X
++ Janssen/X
++ Moolenaar/X
++ Renee/X
++ René/X
++ Renée/X
++ Walter/X
++ # toevoegingen uit de Woordenlijst van 30 mei 1996
++ a capella
++ a fortiori
++ a priori
++ a vista
++ ad hominem
++ afrikaan
++ afterpil
++ alma mater
++ anorexia nervosa
++ apelazerus
++ art nouveau
++ au bain marie
++ auctor intellectualis
++ auctor intellectualis
++ avant la lettre
++ bal masqué
++ basso continuo
++ batavier
++ benefit of the doubt
++ black box
++ black jack
++ black power
++ blue jeans
++ boogie woogie
++ bric à brac
++ bungee jumping
++ capita selecta
++ chaise longue
++ chinezen
++ coming man
++ comme il faut
++ commedia dell' arte
++ communis opinio
++ consilium abeundi
++ couleur locale
++ coûte que coûte
++ dalai lama
++ de jure
++ deus ex machina
++ domus Dei
++ dramatis personae
++ eigener beweging
++ en plein public
++ en profil
++ enfant terrible
++ entre nous
++ fait accompli
++ faux pas
++ femme fatale
++ filet d'anvers
++ fin de siècle
++ finishing touch
++ franse
++ fransman
++ gotisch
++ happy few
++ hora est
++ hors d'oeuvre
++ in absentia
++ in abstracto
++ in allen gevalle
++ in extenso
++ in koelen bloede
++ in memoriam
++ in statu nascendi
++ in triplo
++ in voce
++ invite
++ ipso facto
++ jalousie de métier
++ jehova
++ jeune premier
++ joint venture
++ jus d'orange
++ kalis
++ kousjer
++ laisser faire
++ laissez passer
++ lapis lazuli
++ latino
++ logos
++ maître d'hôtel
++ minimal art
++ naar den vleze
++ non sequitur
++ off line
++ om den brode
++ on line
++ oratio pro domo
++ orchestreren
++ pain à la grecque
++ par excellence
++ pas de deux
++ paso doble
++ patates frites
++ peau de pêche
++ perpetuum mobile
++ plat du jour
++ pool
++ poste restante
++ pot au feu
++ procesverbaal
++ promilitair
++ public relations
++ pur sang
++ qualitate qua
++ questionnaire
++ rector magnificus
++ remedial teacher
++ remedial teaching
++ rigor mortis
++ romein
++ self-fulfilling prophecy
++ septic tank
++ short story
++ sotto voce
++ stehgeiger
++ sub rosa
++ sur place
++ t-bonesteak
++ te bestemder plaatse
++ te bestemder tijd
++ te elfder ure
++ te eniger tijd
++ te gelde maken
++ te onzen voordele
++ ten algemenen nutte
++ ten anderen male
++ ten besluite
++ ten bewijze
++ ten derde male
++ ten geschenke geven
++ ten geschenke krijgen
++ ten tweede male
++ ten vervolge op
++ ter aangehaalder plaatse
++ ter bestemder plaatse
++ ter bestemder tijd
++ ter beurze
++ ter eenre zijde
++ ter elfder ure
++ ter kerke
++ ter ore
++ terneerliggen
++ terneerslaan
++ terneervallen
++ tertiair
++ top secret
++ tot bloedens toe
++ total loss
++ turken
++ upper ten
++ ups and downs
++ van koninklijken bloede
++ van zinnens zijn
++ viola da gamba
++ white spirit
++ wishful thinking
++ à gogo
++ à propos
diff --git a/src/spell/pl_PL.diff b/src/spell/pl_PL.diff
index 56de6e1..562d59a 100644
--- a/src/spell/pl_PL.diff
+++ b/src/spell/pl_PL.diff
@@ -1,10 +1,31 @@
 *** pl_PL.orig.aff	Wed Mar 30 06:50:02 2005
---- pl_PL.aff	Sat Apr 23 20:11:15 2005
+--- pl_PL.aff	Sat Jun 18 19:45:45 2005
 ***************
 *** 3,4 ****
 --- 3,7 ----
   
-+ FOL ±¢³µ¶¨¹º»¼¾¿±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ LOW ±¢³µ¶¨¹º»¼¾¿±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
-+ UPP ¡¢£¥¦¨©ª«¬®¯±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ
++ FOL ±¢³µ¶¨¹º»¼¾¿±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
++ LOW ±¢³µ¶¨¹º»¼¾¿±²³´µ¶·¸¹º»¼½¾¿àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ
++ UPP ¡¢£¥¦¨©ª«¬®¯±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ
   
+***************
+*** 6614 ****
+--- 6617,6634 ----
+  SFX y   y         ie        jmy
++ 
++ # REP entries proposed by Mikolaj Machowski:
++ REP 14
++ REP b   p
++ REP p   b
++ REP ¿   rz
++ REP rz  ¿
++ REP w   f
++ REP f   w
++ REP ó   u
++ REP u   ó
++ REP ci  æ
++ REP æ   ci
++ REP si  ¶
++ REP ¶   si
++ REP ni  ñ
++ REP ñ   ni
diff --git a/src/structs.h b/src/structs.h
index 18915cf..b9792b1 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -1957,7 +1957,7 @@
     char_u	*actext;	    /* accelerator text (after TAB) */
     int		priority;	    /* Menu order priority */
 #ifdef FEAT_GUI
-    void	(*cb)();	    /* Call-back routine */
+    void	(*cb) __ARGS((vimmenu_T *));	    /* Call-back routine */
 #endif
 #ifdef FEAT_TOOLBAR
     char_u	*iconfile;	    /* name of file for icon or NULL */
diff --git a/src/term.c b/src/term.c
index 9ff2938..525577c 100644
--- a/src/term.c
+++ b/src/term.c
@@ -814,16 +814,16 @@
     {(int)KS_CCO,	"8"},			/* allow 8 colors */
     {(int)KS_ME,	IF_EB("\033[0m", ESC_STR "[0m")},
     {(int)KS_MR,	IF_EB("\033[7m", ESC_STR "[7m")},
-    {(int)KS_MD,        IF_EB("\033[1m", ESC_STR "[1m")},  /* bold mode */
-    {(int)KS_SE,        IF_EB("\033[22m", ESC_STR "[22m")},/* normal mode */
-    {(int)KS_UE,        IF_EB("\033[24m", ESC_STR "[24m")},/* exit underscore mode */
-    {(int)KS_US,        IF_EB("\033[4m", ESC_STR "[4m")},  /* underscore mode */
-    {(int)KS_CZH,       IF_EB("\033[34;43m", ESC_STR "[34;43m" )},  /* italic mode: blue text on yellow */
-    {(int)KS_CZR,       IF_EB("\033[0m", ESC_STR "[0m")},           /* italic mode end */
-    {(int)KS_CAB,       IF_EB("\033[4%dm", ESC_STR "[4%dm" )},      /* set background color (ANSI) */
-    {(int)KS_CAF,       IF_EB("\033[3%dm", ESC_STR "[3%dm" )},      /* set foreground color (ANSI) */
-    {(int)KS_CSB,       IF_EB("\033[102;%dm", ESC_STR "[102;%dm" )},    /* set screen background color */
-    {(int)KS_CSF,       IF_EB("\033[101;%dm", ESC_STR "[101;%dm" )},    /* set screen foreground color */
+    {(int)KS_MD,	IF_EB("\033[1m", ESC_STR "[1m")},  /* bold mode */
+    {(int)KS_SE,	IF_EB("\033[22m", ESC_STR "[22m")},/* normal mode */
+    {(int)KS_UE,	IF_EB("\033[24m", ESC_STR "[24m")},/* exit underscore mode */
+    {(int)KS_US,	IF_EB("\033[4m", ESC_STR "[4m")},  /* underscore mode */
+    {(int)KS_CZH,	IF_EB("\033[34;43m", ESC_STR "[34;43m")},  /* italic mode: blue text on yellow */
+    {(int)KS_CZR,	IF_EB("\033[0m", ESC_STR "[0m")},	    /* italic mode end */
+    {(int)KS_CAB,	IF_EB("\033[4%dm", ESC_STR "[4%dm")},	    /* set background color (ANSI) */
+    {(int)KS_CAF,	IF_EB("\033[3%dm", ESC_STR "[3%dm")},	    /* set foreground color (ANSI) */
+    {(int)KS_CSB,	IF_EB("\033[102;%dm", ESC_STR "[102;%dm")},	/* set screen background color */
+    {(int)KS_CSF,	IF_EB("\033[101;%dm", ESC_STR "[101;%dm")},	/* set screen foreground color */
     {(int)KS_MS,	"y"},
     {(int)KS_UT,	"y"},
     {(int)KS_LE,	"\b"},
@@ -842,13 +842,17 @@
     {K_DOWN,		IF_EB("\033[B", ESC_STR "[B")},
     {K_RIGHT,		IF_EB("\033[C", ESC_STR "[C")},
     {K_LEFT,		IF_EB("\033[D", ESC_STR "[D")},
+    {K_F1,		IF_EB("\033[11~", ESC_STR "[11~")},
+    {K_F2,		IF_EB("\033[12~", ESC_STR "[12~")},
+    {K_F3,		IF_EB("\033[13~", ESC_STR "[13~")},
+    {K_F4,		IF_EB("\033[14~", ESC_STR "[14~")},
+    {K_F5,		IF_EB("\033[15~", ESC_STR "[15~")},
     {K_F6,		IF_EB("\033[17~", ESC_STR "[17~")},
     {K_F7,		IF_EB("\033[18~", ESC_STR "[18~")},
     {K_F8,		IF_EB("\033[19~", ESC_STR "[19~")},
     {K_F9,		IF_EB("\033[20~", ESC_STR "[20~")},
     {K_F10,		IF_EB("\033[21~", ESC_STR "[21~")},
-/*  {K_F11,		IF_EB("\033[23~", ESC_STR "[23~")},
-			*  (ESC) should not define, sometimes does not work */
+    {K_F11,		IF_EB("\033[23~", ESC_STR "[23~")},
     {K_F12,		IF_EB("\033[24~", ESC_STR "[24~")},
     {K_F13,		IF_EB("\033[25~", ESC_STR "[25~")},
     {K_F14,		IF_EB("\033[26~", ESC_STR "[26~")},
diff --git a/src/undo.c b/src/undo.c
index 1abd41d..0ad3ae1 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -79,7 +79,8 @@
 static int	undo_undoes = FALSE;
 
 /*
- * save the current line for both the "u" and "U" command
+ * Save the current line for both the "u" and "U" command.
+ * Returns OK or FAIL.
  */
     int
 u_save_cursor()
diff --git a/src/version.h b/src/version.h
index 3e32fc7..7307eb2 100644
--- a/src/version.h
+++ b/src/version.h
@@ -36,5 +36,5 @@
 #define VIM_VERSION_NODOT	"vim70aa"
 #define VIM_VERSION_SHORT	"7.0aa"
 #define VIM_VERSION_MEDIUM	"7.0aa ALPHA"
-#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jun 19)"
-#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jun 19, compiled "
+#define VIM_VERSION_LONG	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jun 22)"
+#define VIM_VERSION_LONG_DATE	"VIM - Vi IMproved 7.0aa ALPHA (2005 Jun 22, compiled "
diff --git a/src/window.c b/src/window.c
index e57976c..c9c6c99 100644
--- a/src/window.c
+++ b/src/window.c
@@ -458,11 +458,8 @@
     case 'f':
     case Ctrl_F:
 		CHECK_CMDWIN
-#ifdef FEAT_VISUAL
-		reset_VIsual_and_resel();	/* stop Visual mode */
-#endif
-		ptr = file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP,
-								     Prenum1);
+
+		ptr = grab_file_name(Prenum1);
 		if (ptr != NULL)
 		{
 #ifdef FEAT_GUI
@@ -4478,6 +4475,30 @@
 
 #if defined(FEAT_SEARCHPATH) || defined(PROTO)
 /*
+ * Get the file name at the cursor.
+ * If Visual mode is active, use the selected text if it's in one line.
+ * Returns the name in allocated memory, NULL for failure.
+ */
+    char_u *
+grab_file_name(count)
+    long count;
+{
+# ifdef FEAT_VISUAL
+    if (VIsual_active)
+    {
+	int	len;
+	char_u	*ptr;
+
+	if (get_visual_text(NULL, &ptr, &len) == FAIL)
+	    return NULL;
+	return find_file_name_in_path(ptr, len,
+		     FNAME_MESS|FNAME_EXP|FNAME_REL, count, curbuf->b_ffname);
+    }
+# endif
+    return file_name_at_cursor(FNAME_MESS|FNAME_HYP|FNAME_EXP|FNAME_REL, count);
+}
+
+/*
  * Return the file name under or after the cursor.
  *
  * The 'path' option is searched if the file name is not absolute.