diff --git a/Makefile b/Makefile
index b8e8e9ccfa93f98051a5a27a8e3bd680c996f82d_TWFrZWZpbGU=..3fb0476970d675280d434564e629a8efd8786ab9_TWFrZWZpbGU= 100644
--- a/Makefile
+++ b/Makefile
@@ -19,7 +19,7 @@
 
 # This XEmacs package contains independent single file lisp packages
 
-VERSION = 1.12
+VERSION = 1.13
 AUTHOR_VERSION =
 MAINTAINER = XEmacs Development Team <xemacs-beta@xemacs.org>
 PACKAGE = text-modes
diff --git a/flyspell.el b/flyspell.el
index b8e8e9ccfa93f98051a5a27a8e3bd680c996f82d_Zmx5c3BlbGwuZWw=..3fb0476970d675280d434564e629a8efd8786ab9_Zmx5c3BlbGwuZWw= 100644
--- a/flyspell.el
+++ b/flyspell.el
@@ -26,7 +26,12 @@
 ;;
 ;; Flyspell is a minor Emacs mode performing on-the-fly spelling
 ;; checking.
+;;
+;; To install flyspell, add this to your ~/.emacs file:
+;;
+;;    (autoload 'flyspell-mode "flyspell" "On-the-fly spelling checking" t)
+;;    (autoload 'global-flyspell-mode "flyspell" "On-the-fly spelling" t)
 ;;                                                                  
 ;; To enable Flyspell minor mode, type Meta-x flyspell-mode.
 ;; This applies only to the current buffer.
 ;;                                                                  
@@ -29,10 +34,15 @@
 ;;                                                                  
 ;; To enable Flyspell minor mode, type Meta-x flyspell-mode.
 ;; This applies only to the current buffer.
 ;;                                                                  
+;; Or if you want to turn Flyspell mode on in many buffers, add this to
+;; you ~/.emacs file:
+;;
+;;    (global-flyspell-mode t)
+;;                                                                  
 ;; Note: consider setting the variable ispell-parser to `tex' to
 ;; avoid TeX command checking; use `(setq ispell-parser 'tex)'
 ;; _before_ entering flyspell.
 ;;                                                                  
 ;; Some user variables control the behavior of flyspell.  They are
 ;; those defined under the `User variables' comment.
@@ -33,13 +43,9 @@
 ;; Note: consider setting the variable ispell-parser to `tex' to
 ;; avoid TeX command checking; use `(setq ispell-parser 'tex)'
 ;; _before_ entering flyspell.
 ;;                                                                  
 ;; Some user variables control the behavior of flyspell.  They are
 ;; those defined under the `User variables' comment.
-;; 
-;; Note: as suggested by Yaron M. Minsky, if you use flyspell when
-;; sending mails, you should add the following:
-;;    (add-hook 'mail-send-hook 'flyspell-mode-off)
 
 ;;; Code:
 (require 'ispell)
@@ -51,7 +57,6 @@
   "Spellchecking on the fly."
   :tag "FlySpell"
   :prefix "flyspell-"
-  :group 'processes
-  :version "20.3")
+  :group 'processes)
 
 ;*---------------------------------------------------------------------*/
@@ -56,6 +61,6 @@
 
 ;*---------------------------------------------------------------------*/
-;*    User variables ...                                               */
+;*    User configuration ...                                           */
 ;*---------------------------------------------------------------------*/
 (defcustom flyspell-highlight-flag t
   "*How Flyspell should indicate misspelled words.
@@ -73,7 +78,7 @@
   :group 'flyspell
   :type 'boolean)
 
-(defcustom flyspell-duplicate-distance 10000
+(defcustom flyspell-duplicate-distance -1
   "*The maximum distance for finding duplicates of unrecognized words.
 This applies to the feature that when a word is not found in the dictionary,
 if the same spelling occurs elsewhere in the buffer,
@@ -104,6 +109,7 @@
 (defcustom flyspell-default-delayed-commands
   '(self-insert-command
     delete-backward-char
+    backward-or-forward-delete-char
     delete-char)
   "The standard list of delayed commands for Flyspell.
 See `flyspell-delayed-commands'."
@@ -122,14 +128,9 @@
   :group 'flyspell
   :type 'boolean)
 
-(defcustom flyspell-consider-dash-as-word-delimiter-flag nil
-  "*Non-nil means that the `-' char is considered as a word delimiter."
-  :group 'flyspell
-  :type 'boolean)
-
 (defcustom flyspell-incorrect-hook nil
   "*List of functions to be called when incorrect words are encountered.
 Each function is given two arguments: the beginning and the end
 of the incorrect region."
   :group 'flyspell)
 
@@ -130,11 +131,13 @@
 (defcustom flyspell-incorrect-hook nil
   "*List of functions to be called when incorrect words are encountered.
 Each function is given two arguments: the beginning and the end
 of the incorrect region."
   :group 'flyspell)
 
-(defcustom flyspell-multi-language-p t
-  "*Non-nil means that Flyspell can be used with multiple languages.
-This mode works by starting a separate Ispell process for each buffer,
-so that each buffer can use its own language."
+(defcustom flyspell-default-dictionary "american"
+  "A string that is the name of the default dictionary.
+This is passed to the ispell-change-dictionary when flyspell is started.
+If the variables ispell-local-dictionary or ispell-dictionary are non nil
+when flyspell is started, the value of that variables is used instead
+of flyspell-default-dictionary to select the default dictionary."
   :group 'flyspell
@@ -140,5 +143,30 @@
   :group 'flyspell
-  :type 'boolean)
+  :type 'string)
+
+(defcustom flyspell-global-modes t
+  "*Modes for which Flyspell mode is automagically turned on.
+Global Flyspell mode is controlled by the `global-flyspell-mode' command.
+If nil, means no modes have Flyspell mode automatically turned on.
+If t, all modes have it automatically turned on.
+If a list, it should be a list of `major-mode' symbol names for which Flyspell
+mode should be automatically turned on.  The sense of the list is negated if it
+begins with `not'.  For example:
+ (tex-mode mail-mode)
+means that Flyspell mode is turned on for buffers in tex and mail-mode
+modes only."
+  :type '(choice (const :tag "none" nil)
+		 (const :tag "all" t)
+		 (set :menu-tag "mode specific" :tag "modes"
+		      :value (not)
+		      (const :tag "Except" not)
+		      (repeat :inline t (symbol :tag "mode"))))
+  :group 'flyspell)
+
+(defcustom flyspell-dictionaries-that-consider-dash-as-word-delimiter
+  '("francais" "deutsch8")
+  "List of dictionary names that consider `-' as word delimiter."
+  :group 'flyspell
+  :type '(repeat (string)))
 
 ;;;###autoload
 (defcustom flyspell-mode-line-string " Fly"
@@ -213,7 +241,6 @@
 ;*---------------------------------------------------------------------*/
 ;*    The minor mode declaration.                                      */
 ;*---------------------------------------------------------------------*/
-;;;###autoload
 (defvar flyspell-mode nil)
 (make-variable-buffer-local 'flyspell-mode)
 
@@ -217,7 +244,6 @@
 (defvar flyspell-mode nil)
 (make-variable-buffer-local 'flyspell-mode)
 
-;;;###autoload
 (defvar flyspell-mode-map (make-sparse-keymap))
 (defvar flyspell-mouse-map (make-sparse-keymap))
 
@@ -254,7 +280,16 @@
   (if (string-match "19.*XEmacs" emacs-version)
       'keymap
     'local-map))
-   
+
+;; dash character machinery
+(defvar flyspell-consider-dash-as-word-delimiter-flag nil
+   "*Non-nil means that the `-' char is considered as a word delimiter.")
+(make-variable-buffer-local 'flyspell-consider-dash-as-word-delimiter-flag)
+(defvar flyspell-dash-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-dictionary)
+(defvar flyspell-dash-local-dictionary nil)
+(make-variable-buffer-local 'flyspell-dash-local-dictionary)
+
 ;*---------------------------------------------------------------------*/
 ;*    Highlighting                                                     */
 ;*---------------------------------------------------------------------*/
@@ -284,9 +319,15 @@
 With no argument, this command toggles Flyspell mode.
 With a prefix argument ARG, turn Flyspell minor mode on iff ARG is positive.
   
+Alternatively, you can use Global Flyspell mode to automagically turn on 
+Flyspell in buffers whose major mode supports it and whose major mode is one
+of `flyspell-global-modes'. For example, put in your ~/.emacs:
+
+ (global-flyspell-mode t)
+
 Bindings:
 \\[ispell-word]: correct words (using Ispell).
 \\[flyspell-auto-correct-word]: automatically correct word.
 \\[flyspell-correct-word] (or mouse-2): popup correct words.
 
 Hooks:
@@ -287,10 +328,10 @@
 Bindings:
 \\[ispell-word]: correct words (using Ispell).
 \\[flyspell-auto-correct-word]: automatically correct word.
 \\[flyspell-correct-word] (or mouse-2): popup correct words.
 
 Hooks:
-flyspell-mode-hook is runner after flyspell is entered.
+flyspell-mode-hook is run after flyspell is entered.
 
 Remark:
 `flyspell-mode' uses `ispell-mode'.  Thus all Ispell options are
@@ -306,16 +347,124 @@
 
 flyspell-buffer checks the whole buffer."
   (interactive "P")
-  ;; we set the mode on or off
-  (setq flyspell-mode (not (or (and (null arg) flyspell-mode)
-			       (<= (prefix-numeric-value arg) 0))))
-  (if flyspell-mode
-      (flyspell-mode-on)
-    (flyspell-mode-off))
-  ;; we force the modeline re-printing
-  (set-buffer-modified-p (buffer-modified-p)))
+  (let ((old-flyspell-mode flyspell-mode))
+    ;; Mark the mode as on or off.
+    (setq flyspell-mode (not (or (and (null arg) flyspell-mode)
+				 (<= (prefix-numeric-value arg) 0))))
+    ;; Do the real work.
+    (unless (eq flyspell-mode old-flyspell-mode)
+      (if flyspell-mode
+	  (flyspell-mode-on)
+	(flyspell-mode-off))
+      ;; Force modeline redisplay.
+      (set-buffer-modified-p (buffer-modified-p)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-buffers ...                                             */
+;*    -------------------------------------------------------------    */
+;*    For remembering buffers running flyspell                         */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-buffers nil)
+ 
+;*---------------------------------------------------------------------*/
+;*    global-flyspell-mode ...                                         */
+;*    -------------------------------------------------------------    */
+;*    I have stolen this implementation from Global Font Lock mode.    */
+;*    I use the exact same trick.                                      */
+;*---------------------------------------------------------------------*/
+;;;###autoload
+(defun global-flyspell-mode (&optional arg message)
+  "Toggle Global Flyspell mode.
+With prefix ARG, turn Global Flyspell mode on if and only if ARG is positive.
+Displays a message saying whether the mode is on or off if MESSAGE is non-nil.
+Returns the new status of Global Flyspell mode (non-nil means on).
+
+When Global Flyspell mode is enabled, Flyspell mode is automagically
+turned on in a buffer if its major mode is one of `flyspell-global-modes'."
+  (interactive "P\np")
+  (let ((on-p (if arg
+		  (> (prefix-numeric-value arg) 0)
+		(not global-flyspell-mode))))
+    (cond (on-p
+	   (add-hook 'find-file-hooks 'turn-on-flyspell-if-enabled)
+	   (add-hook 'first-change-hook 'turn-on-flyspell-if-enabled)
+	   (mapcar '(lambda (buffer)
+		      (with-current-buffer buffer
+			(turn-on-flyspell-if-enabled)))
+		   (buffer-list)))
+	  (t
+	   (remove-hook 'find-file-hooks 'turn-on-flyspell-if-enabled)
+	   (remove-hook 'first-change-hook 'turn-on-flyspell-if-enabled)
+	   (mapcar '(lambda (buffer)
+		      (with-current-buffer buffer
+			(when flyspell-mode
+			  (flyspell-mode))))
+		   (buffer-list))))
+    (when message
+      (message "Global Flyspell mode %s." (if on-p "enabled" "disabled")))
+    (setq global-flyspell-mode on-p)))
+
+;*---------------------------------------------------------------------*/
+;*    global-flyspell-mode ...                                         */
+;*---------------------------------------------------------------------*/
+(defcustom global-flyspell-mode nil
+  "Toggle Global Flyspell mode.
+When Global Flyspell mode is enabled, Flyspell mode is automagically
+turned on in a buffer if its major mode is one of `flyspell-global-modes'.
+You must modify via \\[customize] for this variable to have an effect."
+  :set (lambda (symbol value)
+	 (global-flyspell-mode (or value 0)))
+  :type 'boolean
+  :group 'flyspell
+  :require 'flyspell)
+
+;*---------------------------------------------------------------------*/
+;*    turn-on-flyspell-if-enabled ...                                  */
+;*---------------------------------------------------------------------*/
+(defun turn-on-flyspell-if-enabled ()
+  ;; Gross hack warning: Delicate readers should avert eyes now.
+  ;; Turn on Flyspell mode if it's supported by the major mode and enabled by
+  ;; the user.
+  (if (flyspell-global-mode-enabled-p (current-buffer))
+      (flyspell-mode t)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-global-mode-enabled-p ...                               */
+;*---------------------------------------------------------------------*/
+(defun flyspell-global-mode-enabled-p (buffer)
+  "Does BUFFER need to activate Flyspell?"
+  (and global-flyspell-mode
+       (not (flyspell-minibuffer-p buffer))
+       (or (eq flyspell-global-modes t)
+	   (if (eq (car-safe flyspell-global-modes) 'not)
+	       (not (memq major-mode (cdr flyspell-global-modes)))
+	     (memq major-mode flyspell-global-modes)))))
+	    
+;*---------------------------------------------------------------------*/
+;*    flyspell-minibuffer-p ...                                        */
+;*---------------------------------------------------------------------*/
+(defun flyspell-minibuffer-p (buffer)
+  "Is BUFFER a minibuffer?"
+  (let ((ws (get-buffer-window-list buffer t)))
+    (and (consp ws) (window-minibuffer-p (car ws)))))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-accept-buffer-local-defs ...                            */
+;*---------------------------------------------------------------------*/
+(defun flyspell-accept-buffer-local-defs ()
+  (ispell-accept-buffer-local-defs)
+  (if (not (and (eq flyspell-dash-dictionary ispell-dictionary)
+		(eq flyspell-dash-local-dictionary ispell-local-dictionary)))
+      ;; the dictionary as changed
+      (progn
+	(setq flyspell-dash-dictionary ispell-dictionary)
+	(setq flyspell-dash-local-dictionary ispell-local-dictionary)
+	(if (member (or ispell-local-dictionary ispell-dictionary)
+		    flyspell-dictionaries-that-consider-dash-as-word-delimiter)
+	    (setq flyspell-consider-dash-as-word-delimiter-flag t)
+	  (setq flyspell-consider-dash-as-word-delimiter-flag nil)))))
 
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-mode-on ...                                             */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-mode-on ()
@@ -317,7 +466,7 @@
 
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-mode-on ...                                             */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-mode-on ()
-  "Turn flyspell mode on.  Do not use this; use `flyspell-mode' instead."
+  "Turn Flyspell mode on.  Do not use this; use `flyspell-mode' instead."
   (setq ispell-highlight-face 'flyspell-incorrect-face)
@@ -323,14 +472,12 @@
   (setq ispell-highlight-face 'flyspell-incorrect-face)
-  ;; ispell initialization
-  (if flyspell-multi-language-p
-      (progn
-	(make-variable-buffer-local 'ispell-dictionary)
-	(make-variable-buffer-local 'ispell-process)
-	(make-variable-buffer-local 'ispell-filter)
-	(make-variable-buffer-local 'ispell-filter-continue)
-	(make-variable-buffer-local 'ispell-process-directory)
-	(make-variable-buffer-local 'ispell-parser)))
-  ;; We put the `flyspel-delayed' property on some commands.
+  ;; local dictionaries setup
+  (ispell-change-dictionary
+   (or ispell-local-dictionary flyspell-default-dictionary))
+  ;; we have to force ispell to accept the local definition or
+  ;; otherwise it could be too late, the local dictionary may
+  ;; be forgotten!
+  (flyspell-accept-buffer-local-defs)
+  ;; we put the `flyspel-delayed' property on some commands
   (flyspell-delay-commands)
   ;; we bound flyspell action to post-command hook
   (make-local-hook 'post-command-hook)
@@ -338,8 +485,11 @@
   ;; we bound flyspell action to pre-command hook
   (make-local-hook 'pre-command-hook)
   (add-hook 'pre-command-hook (function flyspell-pre-command-hook) t t)
-
-  ;; Set flyspell-generic-check-word-p based on the major mode.
+  ;; we bound flyspell action to after-change hook
+  (make-local-variable 'after-change-functions)
+  (setq after-change-functions
+	(cons 'flyspell-after-change-function after-change-functions))
+  ;; set flyspell-generic-check-word-p based on the major mode
   (let ((mode-predicate (get major-mode 'flyspell-mode-predicate)))
     (if mode-predicate
 	(setq flyspell-generic-check-word-p mode-predicate)))
@@ -343,10 +493,9 @@
   (let ((mode-predicate (get major-mode 'flyspell-mode-predicate)))
     (if mode-predicate
 	(setq flyspell-generic-check-word-p mode-predicate)))
- 
   ;; the welcome message
   (if flyspell-issue-welcome-flag
       (let ((binding (where-is-internal 'flyspell-auto-correct-word
 					nil 'non-ascii)))
 	(message
 	 (if binding
@@ -347,8 +496,8 @@
   ;; the welcome message
   (if flyspell-issue-welcome-flag
       (let ((binding (where-is-internal 'flyspell-auto-correct-word
 					nil 'non-ascii)))
 	(message
 	 (if binding
-	     (format "Welcome to flyspell.  Use %s or Mouse-2 to correct words."
+	     (format "Welcome to flyspell. Use %s or Mouse-2 to correct words."
 		     (key-description binding))
@@ -354,12 +503,5 @@
 		     (key-description binding))
-	   "Welcome to flyspell.  Use Mouse-2 to correct words."))))
-  ;; we have to kill the flyspell process when the buffer is deleted.
-  ;; (thanks to Jeff Miller and Roland Rosenfeld who sent me this
-  ;; improvement).
-  (add-hook 'kill-buffer-hook
-	    '(lambda ()
-	       (if flyspell-mode
-		   (flyspell-mode-off))))
+	   "Welcome to flyspell. Use Mouse-2 to correct words."))))
   ;; we end with the flyspell hooks
   (run-hooks 'flyspell-mode-hook))
 
@@ -367,7 +509,7 @@
 ;*    flyspell-delay-commands ...                                      */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-delay-commands ()
-  "Install the standard set of delayed commands."
+  "Install the standard set of Flyspell delayed commands."
   (mapcar 'flyspell-delay-command flyspell-default-delayed-commands)
   (mapcar 'flyspell-delay-command flyspell-delayed-commands))
 
@@ -375,7 +517,7 @@
 ;*    flyspell-delay-command ...                                       */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-delay-command (command)
-  "Set COMMAND to be delayed.
+  "Set COMMAND to be delayed, for Flyspell.
 When flyspell `post-command-hook' is invoked because a delayed command
 as been used the current word is not immediatly checked.
 It will be checked only after `flyspell-delay' seconds."
@@ -415,8 +557,10 @@
 ;*    post command hook, we will check, if the word at this position   */
 ;*    has to be spell checked.                                         */
 ;*---------------------------------------------------------------------*/
-(defvar flyspell-pre-buffer nil)
-(defvar flyspell-pre-point  nil)
+(defvar flyspell-pre-buffer     nil)
+(defvar flyspell-pre-point      nil)
+(defvar flyspell-pre-pre-buffer nil)
+(defvar flyspell-pre-pre-point  nil)
 
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-pre-command-hook ...                                    */
@@ -430,4 +574,5 @@
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-mode-off ...                                            */
 ;*---------------------------------------------------------------------*/
+;;;###autoload
 (defun flyspell-mode-off ()
@@ -433,9 +578,5 @@
 (defun flyspell-mode-off ()
-  "Turn flyspell mode off.  Do not use this--use `flyspell-mode' instead."
-  ;; If we have an Ispell process for each buffer,
-  ;; kill the one for this buffer.
-  (if flyspell-multi-language-p
-      (ispell-kill-ispell t))
+  "Turn Flyspell mode off."
   ;; we remove the hooks
   (remove-hook 'post-command-hook (function flyspell-post-command-hook) t)
   (remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t)
@@ -439,6 +580,8 @@
   ;; we remove the hooks
   (remove-hook 'post-command-hook (function flyspell-post-command-hook) t)
   (remove-hook 'pre-command-hook (function flyspell-pre-command-hook) t)
+  (setq after-change-functions (delq 'flyspell-after-change-function
+				     after-change-functions))
   ;; we remove all the flyspell hilightings
   (flyspell-delete-all-overlays)
   ;; we have to erase pre cache variables
@@ -448,6 +591,66 @@
   (setq flyspell-mode nil))
 
 ;*---------------------------------------------------------------------*/
+;*    flyspell-check-pre-word-p ...                                    */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-pre-word-p ()
+  "Return non-nil if we should to check the word before point.
+More precisely, it applies to the word that was before point
+before the current command."
+  (cond
+   ((or (not (numberp flyspell-pre-point))
+	(not (bufferp flyspell-pre-buffer))
+	(not (buffer-live-p flyspell-pre-buffer)))
+    nil)
+   ((and (eq flyspell-pre-pre-point flyspell-pre-point)
+	 (eq flyspell-pre-pre-buffer flyspell-pre-buffer))
+    nil)
+   ((or (and (= flyspell-pre-point (- (point) 1))
+	     (eq (char-syntax (char-after flyspell-pre-point)) ?w))
+	(= flyspell-pre-point (point))
+	(= flyspell-pre-point (+ (point) 1)))
+    nil)
+   ((not (eq (current-buffer) flyspell-pre-buffer))
+    t)
+   ((not (and (numberp flyspell-word-cache-start)
+	      (numberp flyspell-word-cache-end)))
+    t)
+   (t
+    (or (< flyspell-pre-point flyspell-word-cache-start)
+	(> flyspell-pre-point flyspell-word-cache-end)))))
+
+;*---------------------------------------------------------------------*/
+;*    The flyspell after-change-hook, store the change position. In    */
+;*    the post command hook, we will check, if the word at this        */
+;*    position has to be spell checked.                                */
+;*---------------------------------------------------------------------*/
+(defvar flyspell-changes nil)
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-after-change-function ...                               */
+;*---------------------------------------------------------------------*/
+(defun flyspell-after-change-function (start stop len)
+  "Save the current buffer and point for Flyspell's post-command hook."
+  (interactive)
+  (setq flyspell-changes (cons (cons start stop) flyspell-changes)))
+
+;*---------------------------------------------------------------------*/
+;*    flyspell-check-changed-word-p ...                                */
+;*---------------------------------------------------------------------*/
+(defun flyspell-check-changed-word-p (start stop)
+  "Return t when the changed word has to be checked.
+The answer depends of several criteria.
+Mostly we check word delimiters."
+  (cond
+   ((and (>= flyspell-pre-point start) (<= flyspell-pre-point stop))
+    nil)
+   ((let ((pos (point)))
+      (or (>= pos start) (<= pos stop) (= pos (1+ stop))))
+    nil)
+   (t
+    t)))
+  
+;*---------------------------------------------------------------------*/
 ;*    flyspell-check-word-p ...                                        */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-check-word-p ()
@@ -479,30 +682,4 @@
       (sit-for flyspell-delay 0 nil)))))
 
 ;*---------------------------------------------------------------------*/
-;*    flyspell-check-pre-word-p ...                                    */
-;*---------------------------------------------------------------------*/
-(defun flyspell-check-pre-word-p ()
-  "Return non-nil if we should to check the word before point.
-More precisely, it applies to the word that was before point
-before the current command."
-  (cond
-   ((or (not (numberp flyspell-pre-point))
-	(not (bufferp flyspell-pre-buffer))
-	(not (buffer-live-p flyspell-pre-buffer)))
-    nil)
-   ((or (and (= flyspell-pre-point (- (point) 1))
-	     (eq (char-syntax (char-after flyspell-pre-point)) ?w))
-	(= flyspell-pre-point (point))
-	(= flyspell-pre-point (+ (point) 1)))
-    nil)
-   ((not (eq (current-buffer) flyspell-pre-buffer))
-    t)
-   ((not (and (numberp flyspell-word-cache-start)
-	      (numberp flyspell-word-cache-end)))
-    t)
-   (t
-    (or (< flyspell-pre-point flyspell-word-cache-start)
-	(> flyspell-pre-point flyspell-word-cache-end)))))
-  
-;*---------------------------------------------------------------------*/
 ;*    flyspell-post-command-hook ...                                   */
@@ -508,5 +685,16 @@
 ;*    flyspell-post-command-hook ...                                   */
+;*    -------------------------------------------------------------    */
+;*    It is possible that we check several words:                      */
+;*    1- the current word is checked if the predicate                  */
+;*       FLYSPELL-CHECK-WORD-P is true                                 */
+;*    2- the word that used to be the current word before the          */
+;*       THIS-COMMAND is checked if:                                   */
+;*        a- the previous word is different from the current word      */
+;*        b- the previous word as not just been checked by the         */
+;*           previous FLYSPELL-POST-COMMAND-HOOK                       */
+;*    3- the words changed by the THIS-COMMAND that are neither the    */
+;*       previous word nor the current word                            */
 ;*---------------------------------------------------------------------*/
 (defun flyspell-post-command-hook ()
   "The `post-command-hook' used by flyspell to check a word in-the-fly."
   (interactive)
@@ -509,11 +697,9 @@
 ;*---------------------------------------------------------------------*/
 (defun flyspell-post-command-hook ()
   "The `post-command-hook' used by flyspell to check a word in-the-fly."
   (interactive)
-  (if (flyspell-check-word-p)
-      (flyspell-word))
   (if (flyspell-check-pre-word-p)
       (save-excursion
 	(set-buffer flyspell-pre-buffer)
 	(save-excursion
 	  (goto-char flyspell-pre-point)
@@ -515,9 +701,32 @@
   (if (flyspell-check-pre-word-p)
       (save-excursion
 	(set-buffer flyspell-pre-buffer)
 	(save-excursion
 	  (goto-char flyspell-pre-point)
-	  (flyspell-word)))))
+	  (flyspell-word))))
+  (if (flyspell-check-word-p)
+      (progn
+	(flyspell-word)
+	;; we remember which word we have just checked.
+	;; this will be use next time we will check a word
+	;; to compare the next current word with the word
+	;; that as been registered in the pre-command-hook
+	;; that is these variables are used within the predicate
+	;; FLYSPELL-CHECK-PRE-WORD-P
+	(setq flyspell-pre-pre-buffer (current-buffer))
+	(setq flyspell-pre-pre-point  (point)))
+    (progn
+      (setq flyspell-pre-pre-buffer nil)
+      (setq flyspell-pre-pre-point  nil)
+      (setq flyspell-word-cache-end -1)))
+  (while (consp flyspell-changes)
+    (let ((start (car (car flyspell-changes)))
+	  (stop  (cdr (car flyspell-changes))))
+      (if (flyspell-check-changed-word-p start stop)
+	  (save-excursion
+	    (goto-char start)
+	    (flyspell-word)))
+      (setq flyspell-changes (cdr flyspell-changes)))))
 
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-word ...                                                */
@@ -528,5 +737,5 @@
   (if (interactive-p)
       (setq following ispell-following-word))
   (save-excursion
-    (ispell-accept-buffer-local-defs)	; use the correct dictionary
+    (flyspell-accept-buffer-local-defs)	; use the correct dictionary
     (let ((cursor-location (point))	; retain cursor location
@@ -532,5 +741,5 @@
     (let ((cursor-location (point))	; retain cursor location
-	  (word (flyspell-get-word following))
+	  (word (flyspell-get-word following 'full-tex))
 	  start end poss)
       (if (or (eq word nil)
  	      (and (fboundp flyspell-generic-check-word-p)
@@ -557,13 +766,6 @@
 		 (string-equal flyspell-word-cache-word word))
 	    ;; this word had been already checked, we skip
 	    nil)
-	   ((and (eq ispell-parser 'tex)
-		 (flyspell-tex-command-p word))
-	    ;; this is a correct word (because a tex command)
-	    (flyspell-unhighlight-at start)
-	    (if (> end start)
-		(flyspell-unhighlight-at (- end 1)))
-	    t)
 	   (t
 	    ;; we setup the cache
 	    (setq flyspell-word-cache-start start)
@@ -585,7 +787,7 @@
 	    ;; (process-send-string ispell-process "!\n")
 	    ;; back to terse mode.
 	    (setq ispell-filter (cdr ispell-filter))
-	    (if (listp ispell-filter)
+	    (if (consp ispell-filter)
 		(setq poss (ispell-parse-output (car ispell-filter))))
 	    (cond ((eq poss t)
 		   ;; correct
@@ -642,13 +844,6 @@
 	    (if ispell-quit (setq ispell-quit nil)))))))))
 
 ;*---------------------------------------------------------------------*/
-;*    flyspell-tex-command-p ...                                       */
-;*---------------------------------------------------------------------*/
-(defun flyspell-tex-command-p (word)
-  "Return t if WORD is a TeX command."
-  (eq (aref word 0) ?\\))
-
-;*---------------------------------------------------------------------*/
 ;*    flyspell-casechars-cache ...                                     */
 ;*---------------------------------------------------------------------*/
 (defvar flyspell-casechars-cache nil)
@@ -713,5 +908,5 @@
 ;*---------------------------------------------------------------------*/
 ;*    flyspell-get-word ...                                            */
 ;*---------------------------------------------------------------------*/
-(defun flyspell-get-word (following)
+(defun flyspell-get-word (following full-tex)
   "Return the word for spell-checking according to Ispell syntax.
@@ -717,5 +912,5 @@
   "Return the word for spell-checking according to Ispell syntax.
-If optional argument FOLLOWING is non-nil or if `ispell-following-word'
+If argument FOLLOWING is non-nil or if `ispell-following-word'
 is non-nil when called interactively, then the following word
 \(rather than preceding\) is checked when the cursor is not over a word.
 Optional second argument contains otherchars that can be included in word
@@ -719,7 +914,8 @@
 is non-nil when called interactively, then the following word
 \(rather than preceding\) is checked when the cursor is not over a word.
 Optional second argument contains otherchars that can be included in word
-many times.
+many times. The argument FULL-TEX is true if we are fetching a full
+TeX command and nil otherwise.
 
 Word syntax described by `ispell-dictionary-alist' (which see)."
   (let* ((flyspell-casechars (flyspell-get-casechars))
@@ -734,7 +930,9 @@
 			      "+\\)"
 			      (if ispell-many-otherchars-p
 				  "*" "?")))
-	 (tex-prelude "[\\\\{]")
-	 (tex-regexp  (if (eq ispell-parser 'tex)
+	 (tex-prelude (if full-tex
+			  "\\([a-zA-Z*0-9\\]*[\\\\{]\\)"
+			  "[\\\\{]"))
+	 (tex-regexp  (if (and full-tex (eq ispell-parser 'tex))
 			  (concat tex-prelude "?" word-regexp "}?")
 			word-regexp))
@@ -739,6 +937,5 @@
 			  (concat tex-prelude "?" word-regexp "}?")
 			word-regexp))
-		      
 	 did-it-once
 	 start end word)
     ;; find the word
@@ -762,6 +959,10 @@
 	(if (looking-at flyspell-casechars)
 	    (re-search-backward flyspell-not-casechars (point-min) 'move)
 	  (backward-char -1))))
+    ;; when in tex mode, we skip backward until we find a tex prelude
+    (if (and full-tex (eq ispell-parser 'tex))
+	(while (and (> (point) (point-min)) (looking-at tex-prelude))
+	  (backward-char 1)))
     ;; Now mark the word and save to string.
     (if (eq (re-search-forward tex-regexp (point-max) t) nil)
 	nil
@@ -937,7 +1138,7 @@
 to this command."
   (interactive "d")
   ;; use the correct dictionary
-  (ispell-accept-buffer-local-defs)
+  (flyspell-accept-buffer-local-defs)
   (if (eq flyspell-auto-correct-pos pos)
       ;; we have already been using the function at the same location
       (progn
@@ -954,7 +1155,7 @@
 	(setq flyspell-auto-correct-pos (point)))
     ;; retain cursor location
     (let ((cursor-location pos)
-	  (word (flyspell-get-word nil))
+	  (word (flyspell-get-word nil nil))
 	  start end poss)
       ;; destructure return word info list.
       (setq start (car (cdr word))
@@ -968,7 +1169,7 @@
 	       (accept-process-output ispell-process)
 	       (not (string= "" (car ispell-filter)))))
       (setq ispell-filter (cdr ispell-filter))
-      (if (listp ispell-filter)
+      (if (consp ispell-filter)
 	  (setq poss (ispell-parse-output (car ispell-filter))))
       (cond ((or (eq poss t) (stringp poss))
 	     ;; don't correct word
@@ -1064,8 +1265,8 @@
 The word checked is the word at the mouse position."
   (interactive "e")
   ;; use the correct dictionary
-  (ispell-accept-buffer-local-defs)
+  (flyspell-accept-buffer-local-defs)
   ;; retain cursor location (I don't know why but save-excursion here fails).
   (let ((save (point)))
     (mouse-set-point event)
     (let ((cursor-location (point))
@@ -1068,8 +1269,8 @@
   ;; retain cursor location (I don't know why but save-excursion here fails).
   (let ((save (point)))
     (mouse-set-point event)
     (let ((cursor-location (point))
-	  (word (flyspell-get-word nil))
+	  (word (flyspell-get-word nil nil))
 	  start end poss replace)
       ;; destructure return word info list.
       (setq start (car (cdr word))
@@ -1083,7 +1284,7 @@
 	       (accept-process-output ispell-process)
 	       (not (string= "" (car ispell-filter)))))
       (setq ispell-filter (cdr ispell-filter))
-      (if (listp ispell-filter)
+      (if (consp ispell-filter)
 	  (setq poss (ispell-parse-output (car ispell-filter))))
       (cond ((or (eq poss t) (stringp poss))
 	     ;; don't correct word